Arkanoid is a videogame produced by the Japanese software house Taito in 1986. It is considered as the remake of the Atari Breakout arcade, dating back to the 1970’s. Although it is not the first of its kind, it is considered as a milestone of the videogames and over the years it has inspired countless clones and similar games.


The goal of the original game is to break down a certain number of coloured bricks, hitting them with a sphere. At the bottom of the screen is situated the spacecraft "Vaus", that acts as a "base" which can make the sphere bounce against the bricks; of course you must avoid making the sphere fall in the portion of screen below the "Vaus", otherwise there’s a penalty, which consists in losing a life.


This project has made a simplified version of Arkanoid that reflects all the basic functionalities:

  • The sphere bounces and blasts the bricks;
  • There is the concept of life (3 lives are available to try to destroy the brick wall)

 and some of the advanced ones:

  • Some bricks are indestructible;
  • You can vary the rebound angle of the sphere, conferring it an effect through the movement of the spacecraft;
  • You can hit the sphere with the sides of the spacecraft disposed at 45 degrees, by making it reverse its motion maintaining the angle.

For the development it has been used the terasic DE1 board, which assembles FPGA Cyclone II of ALTERA


Altera DE1 image

DE1 Board offers several features for the development of various projects:

  • Altera Cyclone II 2C20 FPGA with 20000 LEs
  • Altera Serial Configuration deivices (EPCS4) for Cyclone II 2C20
  • USB Blaster built in on board for programming and user API controlling
  • JTAG Mode and AS Mode are supported
  • 8Mbyte (1M x 4 x 16) SDRAM
  • 4Mbyte Flash Memory
  • 512Kbyte(256Kx16) SRAM
  • SD Card Socket
  • 4 Push-button switches
  • 10 DPDT switches
  • 8 Green User LEDs
  • 10 Red User LEDs
  • 4 Seven-segment LED displays
  • 50MHz oscillator ,24MHz oscillator ,27MHz oscillator and external clock sources
  • 24-bit CD-Quality Audio CODEC with line-in, line-out, and microphone-in jacks
  • VGA DAC (4-bit R-2R per channel) with VGA out connector
  • RS-232 Transceiver and 9-pin connector
  • PS/2 mouse/keyboard connector
  • Two 40-pin Expansion Headers

For the Arkanoid realization it has been chosen to use:

  • 2 switch “Push-Button” to control the movement to the right and to the left of the bar;
  • 2 switch DPDT to control the game reset and Start/Pause;
  • A 7-segments display to check the remaining “lives”;
  • The VGA output port for the display screen.

Moreover, once the testing phase in which the FPGA Cyclone II programming has been carried out with JTAG methods, it has also been used the EPCS4 eeprom to save the code permanently.
The development software used is Quartus II provided by Altera. For the purpose of this project suffices the web version that can be downloaded directly from Altera web site.
This software gives you tools to realize all the necessary steps to realize the project:

  • Graphical  editor for schematic
  • Text editor to create files in VHDL
  • Interface to JTAG or AS programming mode

 




Next Page

Frequency Divider

Its task is to divide the 50 MHz clock frequency of a factor two, provided by an oscillator mounted on the TERASIC DE1 Board. This division is necessary to obtain the frequency of 25 MHz required for the VGA operation mode: 640x480 pixels at 25 MHz.

VGA Interface:

As seen in the introduction, the TERASIC DE1 tab makes available a VGA output with a 16pin connector. The synchronization signals are directly managed by the Cyclone II FPGA and there is an analogical digital converter (4bit DAC) which produces the R G and B analogical signals.


Picture 1 - Terasic DE1 VGA Circuit

The resolution supported is 640x480 to whom corresponds a 25 MHz dot clock and a 60 MHz refresh; that means that are designed 60 screens per second. The image display on monitor is seen through lines. Once you’ve drown a line and have waited the necessary lag time (Front Porch) to switch from line to line, you draw the next line until you’ve drown the whole screen. At this point you start over.


Picture 2 - Temporal diagram of the horizontal sync signal


Picture 3 – Temporal specifications

A low active pulse of an a-duration is applied to the horizontal sync signal of the VGA port; this period defines a data row. The RGB input of the monitor, must be driven to 0 Volt for a period of time called back porch after the arrival of the hsync pulse. Later, during period c, every single pixel relative to that line is drawn on the output. Finally you wait for the d time, Front Porch, where the RGB signal is once again driven to 0 Volt until the next hsync. The graph of the vertical sync is the same, with the difference that the arrival of the vsync means the end of a frame and the beginning of the next one.


Next Page

Most of the project, for both the operation logic and the visualization on screen, was inserted in a single VHDL file called myArkanoid. This module deals with the VGA sync, the management of the input switch and the 7-segments display, the motion and the graphics of the components of the game.


Vga Sync:

The creation of the signal due to a h_cnt counter which is incremented at every clock beat ( 25Mhz ). The h_sync signal is driven by the value that h_cnt takes on, to respect the times of a standard VGA 640x480. In particular h_cnt changes from 0 to 799, a range of values corresponding to the total period of the line, that is 31,7 µs (a+b+c+d in the graph of Picture 3); the signal h_sync remains high for h_cnt that changes between 0 and 659, it is set to 0 when h_cnt takes values between 660 and 755, then it is again set to 1 until you reach 799. Unlike the previous graph, this routine initialises the counter to 0 when the Display Interval starts, moving the Back Porch after the Front Porch. In this way the operation of the sync doesn’t change, but it allows you to read directly in h_cnt the value of the current column (column).


Picture 4 – Temporal diagram of the horizontal sync signal (in the implementation used)

A similar case is the vertical sync one; particularly v_cnt changes from 0 to 524, a range of values corresponding to the total period of the screen, that is 16.6 ms; the v_sync signal, remains high for v_cnt which changes between 0 and 492; it is set to 0 when v_cnt takes on the values 493 and 494, then it is again set to 1 until you reach 524. There is an additional internal signal, video_en that means video enabled, which is active only if h_cnt is lower than 640 and v_cnt is lower than 480. Therefore, the information about the colour of the pixel is copied from input to output only when video_en is set to 1, that means only if you are in the active screen. In appendix A there’s the fragment of code that realizes what seen.

Input Switch:

To control the motion of the spacecraft have been used two of the four switch Push Button on the tab. These switches maintain the logic state until they are released and they become ideal to realize what necessary. Two others Toggle Switch have been used for the game Reset and for the Pause.

7-Segments Decoder Display:

To drive the 7-segments display it has been used a simple decoder which creates a correspondence between the symbol on the display and the integer corresponding to the remaining lives. The code is very simple and it can be summed up with a banal statement case. In appendix A there’s the fragment of code that realizes it.

Frequency Divider:

The easiest way to realize a frequency divider is by creating a counter that provides an output signal only for certain values. In this particular case suffices a 1 bit counter: in fact, if the counter counts every rising edge (or falling), you already get the clock at half frequency. In appendix A there’s the fragment of code that realizes it.



Next Page

Every graphic element has been realized by turning on or off the pixels that compose it in a certain position of the screen. For example if you want to realize a brick, you must provide the details v_cnt and h_cnt:

IF ((v_cnt >=195) AND (v_cnt <= 204) AND (h_cnt >= 61) AND (h_cnt <= 110))  THEN
red3_signal <= '0'; red2_signal <= '1'; red1_signal <= '1'; red0_signal <= '0';
green3_signal <= '0';      green2_signal <= '1';      green1_signal <= '1';      green0_signal <= '0';
blue3_signal <= '0';       blue2_signal <= '1';       blue1_signal <= '1';       blue0_signal <= '0';  
END IF;

To better understand the meaning of v_cnt and h_cnt you must consider them as lines and columns: if the pixel is located between the lines 195 and 204 and between the columns 61 and 110, it is switched according to the specified colour provided (dark gray). It is evident how complicated is the realization of oblique and curve lines. Let’s see details for the configuration of the graphic of other objects.

 

The Sphere:

What seen before, as introduction about the graphic of the brick, represents how to draw a static object. Inside the game, the sphere must move on the screen, bounce off the walls, obstacles and bricks. To allow the movement, rather than drawing the sphere through fixed points, you must use variables that are constantly updated according to a counter which divides the clock so that the movement is made at a humanly reasonable speed. In the picture, there is the format used for the graphic of the sphere: you can see the ballPositionV and ballPositionH variables that represents the position of the sphere at all times.

The sphere has got two movement components: horizontal ballMovementH and vertical ballMovementV. This variables take on 3 values: 0 negative movement, upwards for the vertical movement and to the left for the horizontal movement; 1 positive movement, downwards and to the right; 2 STOP positions, before starting or at the end of the game. This variables are used to define the increase or decrease of the values that characterize the position of the sphere during the moments in which it changes its direction; in fact if the sphere is moving down, the value of ballPositionV will increase until the moment in which the sphere will collide with an obstacle: so, the value of ballPositionV will decrease at the same way. The case of the horizontal movement is similar. To create the diagonal movement, at each refresh of the position of the sphere, must vary both the horizontal and vertical movement components. In particular for this case, they have been used different impact angles according to the effect impressed to the sphere by the movement of the spacecraft. To vary the angle described by the direction of the sphere, you must change the increase of one of the two components. It has been chosen to use the angle variable that changes the increase of the vertical component.

Picture 7 shows the variation of the movement components of the sphere in the different cases analyzed. The value angle above-mentioned changes between 1 and 3 to create 45°, 60° and 72° angles. This type of variation involves the one of the sphere speed. This happens because if you increase the number of pixel skipped from a position to another one, in a moment the sphere will move more. This feature (which was born as a mistake) was also present in the original videogame. A simple way to rectify this error is by changing the sphere speed, depending on the angle. As mentioned in fact, the sphere changes its position at regular interludes counted by a counter that divides the clock frequency. If you would dynamically change the value to whom the counter is reset, ballSpeed variable at the source, depending on the impact angle of the sphere, it would be a speed adapted to the movement of the sphere. A proof has been done and it is commented in the code. However it has been noticed that slowing the refresh rate of the sphere, its movement is less fluid and the final graphic is not pleasant to see.
The code which realizes what seen is difficult and it remands to the complete source for more specific analysis. To simplify it at the case of a bouncing sphere, maintaining the same angle and a constant speed, in contact with the edges of the screen, here is given the source:

IF(ballMovementV = 1) THEN
       IF (ballPositionV = 450) --Pallina Colpisce fondo schermo
THEN
             ballMovementV:=0;
             ballPositionV:= ballPositionV-1;
       ELSE ballPositionV:= ballPositionV+1;
       END IF;
END IF;
IF(ballMovementV = 0) THEN
IF (ballPositionV =30) --Pallina Colpisce bordo alto dello schermo
THEN
             ballMovementV:=1;
             ballPositionV:= ballPositionV+1;
       ELSE ballPositionV:= ballPositionV-1;
END IF;
END IF;

The same is for the horizontal movement.

 

The Vaus:

The considerations are similar to those made for the movement of the sphere, with the difference that the spacecraft has only got the horizontal movement component. This is how the spacecraft has been realized:

Figura 7 - Realizzazione grafica della navicella

As mentioned, according to the movement of the spacecraft at the moment of the impact with the sphere, an effect is impressed to the sphere which changes its direction. The sides of the spacecraft are placed at 45 degrees and if the sphere impacts this part of the spacecraft, the movement will be completely inverted and will make it cross the same direction in reverse. Picture 9 shows some of the impact angles.


Picture 8 – Impact angles

Edges and Texts:

To make the game graphic more pleasant, there have been created some edges to delimit the movement zone of the sphere. Under the spacecraft it has been designed a graphic which reminds you a water wave. With the same purpose it has been added the header that contains the author, the university, the course this thesis has been realized for, the title of the game and the tab on which the work has been done. The procedure used to draw the letters, is the same you have seen before. Here is an example of how the “S” has been realized and the corresponding code:

IF (((v_cnt = 300 OR v_cnt = 305 OR v_cnt = 310)) AND
       ((h_cnt >=Pause_s_Position+1) AND (h_cnt <= Pause_s_Position+3)))
OR
(((v_cnt >= 301 AND v_cnt<=304) OR v_cnt = 309) AND (h_cnt = Pause_s_Position))
OR
(((v_cnt >= 306 AND v_cnt<=309) OR v_cnt = 301)AND(h_cnt = Pause_s_Position+4))

THEN

red3_signal <= '0'; red2_signal <= '0'; red1_signal <= '0';          red0_signal <= '0';

green3_signal <= '1';green2_signal <= '0';      green1_signal <= '0';      green0_signal <= '0';    

blue3_signal <= '1';   blue2_signal <= '0';       blue1_signal <= '0';       blue0_signal <= '0';      
END IF;

Gradient:

Therefore there are 4bit per colour, 2^12 colour are available, that means 4096 colours. The gradation is given by all the signals red0, red1, red2, red3 ,green0, green1, green2, green3,blue0, blue1,blue2 and blue3. For example with the combination:

red3_signal <= '0'; red2_signal <= '1'; red1_signal <= '1'; red0_signal <= '0';       
green3_signal <= '0';      green2_signal <= '1';      green1_signal <= '1';      green0_signal <= '0';
blue3_signal <= '1';       blue2_signal <= '1';       blue1_signal <= '1';       blue0_signal <= '0';  

you get a light blue gradation.
Exploiting some colour variations, there have been created different gradients to simulate the reflections on the edges, on the sea below, on the spacecraft and on the sphere.

Next Page

FINAL SCHEMATIC AND PIN ASSIGNMENT

Picture 9 – Final schematic

That’s how the design file of the final schematic. As previously said, for the implementation it has been chosen to focus most of the logic in a single block, myArkanoidVHDL. In the picture you can see also the destination pins of the FPGA.

 

BOARD PROGRAMMING: AS MODE

Once you have finished the project and you have run the compilation, circuit analysis and synthesis, and pin assignment stages, you go on with the board programming. There have been used 2 methods:

  • JTAG in a debug phase, useful because the bitstream (.sof) is immediately downloaded in the FPGA and remains there until the turning off of the board;
  • AS, Active Serial Programming: in this case the program file (.pof) is written on the eeprom EPCS4 mounted on the board and stays in memory until it is rewritten. At the opening of the tab will automatically start the starting code on the EPCS4. The following scheme shows the programming phase;  note the PROG position of the RUN/PROG switch, and the next lading phase from the EPCS4 to the FPGA:


Picture 10 – Active Serial configuration scheme

You must leave out the description of the JTAG mode which is explained in other tutorials, and pay attention to the active serial programming, which requires some pre-configurations: in fact the .pof file must be prepared according to the type of eeprom mounted on the tab. Particularly, the DE1 tab mounts a 512Kbyte eeprom, EPCS4.


Then proceed with the necessary settings. Clicking on AssignmentsàDevice appears as follows:

Clicking on Device and Pin Options and selecting the Configurations tab appears:


As shown in the picture, select Active Serial for the Configuration Scheme and the EPCS4 eeprom as device.
Now, every time the software compile and assembles the code, will be created a .pof file, of 512Kbyte compatible with the EPCS4 and so you only have to program it. Clicking on ToolsàProgrammer appears as follows:


  • Select the Active Serial Programming mode.
  • Select the destination device, the EPCS4, clicking on Add Device.
  • Select the .pof  source file clicking on Add File.

Now you proceed with the real programming clicking on Start on the programmer’s window. It is important to make sure the USB-Blaster is selected as Programming Hardware; if not, you must select it clicking on the Hardware setup button. Moreover, you are programming the EEPROM, so the RUN/PROG switch must be positioned on PROG. At the end of the programming, the board must be turned off, the RUN/PROG switch repositioned in RUN and the tab that will start the configuration written on the EPCS4, must be turned on.





Next Page

GAME CONTROLS

The controls you need to play this simple game are a few:

PUSH BUTTON SWITCH KEY0 : Moves the spacecraft to the right;
PUSH BUTTON SWITCH KEY1 : Moves the spacecraft to the left;
TOGGLE SWITCH SW1 : Pauses the game;
TOGGLE SWITCH SW2 : Resets the game.

Picture 11 – Game controls

To complete the breaking down of the brick wall, there are 3 available lives which correspond to 3 spacecrafts. When a spacecraft is destroyed, the sphere is repositioned to the starting position and after about 2 seconds it restarts towards a casual direction; during this period of time, the spacecraft cannot move. Here's a demo:




BIBLIOGRAPHY:

VGA SYNC: http://www.pyroelectro.com/tutorials/vhdl_vga/

Arkanoid Game: http://en.wikipedia.org/wiki/Arkanoid

Terasic DE1 Development Board Manuals: http://www.terasic.com.tw/cgi-bin/page/archive.pl?Language=English&No=83

Altera Web Site: http://www.altera.com/

Here are some portions of code. For full source code, click here.

Vga Sync:

 

--Horizontal Sync
--Reset Horizontal Counter
IF (h_cnt = 799) THEN
h_cnt <= "0000000000";
ELSE
h_cnt <= h_cnt + 1;
END IF;
--Generate Horizontal Sync
IF (h_cnt <= 755) AND (h_cnt >= 659) THEN
h_sync <= '0';
ELSE
h_sync <= '1';
END IF;

--Vertical Sync
--Reset Vertical Counter
IF (v_cnt >= 524) AND (h_cnt >= 699) THEN
v_cnt <= "0000000000";
ELSIF (h_cnt = 699) THEN
v_cnt <= v_cnt + 1;
END IF;
--Generate Vertical Sync
IF (v_cnt <= 494) AND (v_cnt >= 493) THEN
v_sync <= '0';     
ELSE
v_sync <= '1';
END IF;

--Generate Horizontal Data
IF (h_cnt <= 639) THEN
horizontal_en <= '1';
--column <= h_cnt;
ELSE
horizontal_en <= '0';
END IF;
--Generate Vertical Data
IF (v_cnt <= 479) THEN
vertical_en <= '1';
--row <= v_cnt;
ELSE
vertical_en <= '0';
END IF;

7-segments decoder display:


case vite is
when 0 => leds1 <= "0111111";
when 1 => leds1 <="0000110”;    
when 2 => leds1 <= "1011011”;   
when 3 => leds1 <="1001111”;
when others => NULL;
end case;

Frequency divider:


ENTITY dimezzaClock IS
PORT (clock_f : IN STD_LOGIC;
clock_f_mezzi : OUT STD_LOGIC);
END dimezzaClock;

ARCHITECTURE comportamento OF dimezzaClock IS
SIGNAL conta : STD_LOGIC_VECTOR(0 DOWNTO 0);
BEGIN
PROCESS (clock_f)
BEGIN
IF clock_f = '0' AND clock_f'event
THEN conta <= conta + 1;
END IF;
END PROCESS;
clock_f_mezzi <= conta(0);
END comportamento;