Wednesday, 27 April 2016

PacMan running on the Mimas V2 FPGA Development Board

I recently found out that it is possible to run PacMan natively on the Numato Labs Mimas V2 development board.  Being able to implement PacMan on an FPGA is kind of like a right of passage in the FPGA circles.  I have to be honest...I had help!

Goran Mahovlić - a fellow Mimas V2 user pointed me towards this Git Repository which had an 

implementation of PacMan available for download:

https://github.com/Saanlima/Pepino/tree/master/Projects/Pepino-pacman

I downloaded a copy of it to my hardisk and then loaded up the project (pacman_LX9.ise) in Xilinx WebISE:



Some of the code is written in VHDL and some of the code is written in verilog.  The parts we need to edit are the Design Properties, the UCF file and the top level verilog file.  Lets change the design properties first to ensure we are using the correct FPGA device for the Mimas V2 Development board:


  
In the screen that appears change the parameters to match those in the image below:


Click OK to continue...

Next we need to edit the UCF file to account for the Mimas V2 board.  The design was written for a 50 MHz source clock.  However the Mimas V2 has a 100 MHz source clock.  We need to change the UCF file to utilise a 100 MHz source clock and all the connections required to the DIP switches, LEDS, VGA connector and push buttons.  Select the file Pacman.UCF and open it....then delete all of the text in file and paste in the code below:

## NUMATO Mimas V2 ucf file
## http://numato.com/
## PACMAN UCF by Alex

CONFIG VCCAUX  = 3.3;

##Clock signal 100 MHz

NET "SYS_CLK" LOC = V10 | IOSTANDARD = LVCMOS33 | PERIOD = 100MHz;
NET "SYS_CLK" TNM_NET = "sys_clk_pin";

TIMESPEC TS_sys_clk_pin = PERIOD "sys_clk_pin" 100 MHz HIGH 50 %;

# LEDS

NET "LED[3]" LOC = P15 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST;
NET "LED[2]" LOC = U18 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST;
NET "LED[1]" LOC = T17 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST;
NET "LED[0]" LOC = T18 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST;

# DIP Switches for one player, two player and credit                                                                                   

#DP 8
NET "SW[0]" LOC = C17 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST | PULLUP;
NET "SW[1]" LOC = C18 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST | PULLUP;
NET "SW[2]" LOC = D17 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST | PULLUP;
NET "SW[3]" LOC = D18 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST | PULLUP;

# Push Buttons Switches For Joystick                                                                              

#SW6 - FIRE
NET "JOYSTICK[4]" LOC = P1 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST | PULLUP;

#SW1 RIGHT
NET "JOYSTICK[3]" LOC = M18 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST | PULLUP;

#SW2 LEFT
NET "JOYSTICK[2]" LOC = L18 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST | PULLUP;

#SW1 DOWN
NET "JOYSTICK[1]" LOC = L17 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST | PULLUP;

#SW3 UP
NET "JOYSTICK[0]" LOC = M16 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST | PULLUP;

# Audio                                                                                        #

# Audio Left               
NET "audio_l" LOC = B16 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST;
# Audio Right
NET "audio_r" LOC = A16 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST;

# VGA Connections

NET "VGA_HSYNC"   LOC = B12 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST;
NET "VGA_VSYNC"   LOC = A12 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST;

NET "VGA_RED[2]"  LOC = C9  | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST;
NET "VGA_RED[1]"  LOC = B9  | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST;
NET "VGA_RED[0]"  LOC = A9  | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST;

NET "VGA_GREEN[2]" LOC = C11 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST;
NET "VGA_GREEN[1]" LOC = A10 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST;
NET "VGA_GREEN[0]" LOC = C10 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST;

NET "VGA_BLUE[1]" LOC = A11 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST;
NET "VGA_BLUE[0]" LOC = B11 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST;

Save the file once you have done that - always a good idea.

Next we need to edit the module called pacman_top.v to account for the 100 MHz source clock. Load up the file in the internal WebISE text editor and navigate to the following section of code:


Replace the code present there with the code below:

   PLL_BASE # (
    .CLKIN_PERIOD(10),
    .CLKFBOUT_MULT(5), //set VCO to 10x of CLKIN
    .CLKOUT0_DIVIDE(2),
    .CLKOUT1_DIVIDE(20),
    .CLKOUT2_DIVIDE(10),
    .COMPENSATION("INTERNAL")

The above code changes the clock period, multipliers and dividers used to account for the 100 MHz source clock.  Save the file!

Now implement a top module to compile all the code.  Once complete you should have the following warning labels but no errors:


Next generate a programming file - make sure to select to create a bitstream:


Now upload the code to your Mimas V2 development board - Very exciting times!  Make sure you connect up your development board to the PC and select the appropriate COM port, then select the bin file we just created and then click on upload:


Once it's complete connect up a spare monitor to the VGA port and speakers to the audio port on the Mimas V2 and see PacMan in all it's glory:


The controls are:

SW3 = UP
SW4 = DOWN
SW2 = LEFT
SW1 = RIGHT

In order to start the game set the DIP switch 5 or DIP switch 6 from off to On and the back to Off - then the game will start!

Here is a video of me attempting to play the game one handed - sorry there is no sound - I didn't bother to connect speakers!


I cannot take much credit for this - I believe the original FPGA PacMan implementation was written by MikeJ from http://www.fpgaarcade.com/

This was then ported by the very clever and nice people at Saanlima Electronics for the Pipistrello board.

Finally I couldn't have done this without help from Goran Mahovlić and his FPGA friends! They were kind enough to help whilst they were working on getting HDMI functionality working for the Arduino FPGA implementation!

Here is my source code in case it's required -

Alex's PacMan Source code for Mimas V2

Well that is all for now people - Take care - Langster

P.S  If people are interested I reckon we should have a competition to see who gets the highest scores - NO CHEATING!!!!