Saturday, November 17, 2007

Load bitmap images onto Xilinx Spartan-3 FPGA board

As I mentioned before in this blog about my Hardware Synthesis term project, I designed the copy of Pong game using Verilog and tested it on Xilinx Spartan-3 FPGA Starter Kit. The highlight feature of my project is the ability to display bitmap images as game's components. The following instructions are how to do that.

Note: I will assume that the readers know how to design ASIC using Verilog language with Xilinx Webpack and have some background in computer programming.

First, since I was going to use 640x480 8-color mode, so I prepared 8-color bitmap images of in-game components. These are few examples.



To display these images, we need to store their pixel data somewhere in our circuit. There are few options.

  1. Hard-code the static wire or reg variables, which store pixel data, in the Verilog code. This is going to be easy. But you will suffer from long synthesis, post-place and route time. The size of .v files are going to be unacceptable big too.
  2. Utilize the Block RAMs available as external component on Xilinx Spartan-3 FPGA board. Just set the initial values of these Block RAMs to the pixel data of our images.
In this entry, I am going to use the latter method. For more information about how to use Block RAMs in your design, you can consult this documentation from Xilinx.

No matter which way you chose, we need to convert .jpg, .gif , .png, .bmp, etc. images data into easy-to-understand pixel data. This can be done via a little programming. The following Java program prompts user for an image and convert it to Coefficients File (.coe) for use as initial value of Block RAMs. The format of Coefficient File can be found in the Xilinx documentation I mentioned recently.
The program generates two files, name.coe for color images and name.bw.coe for black and white images. BW images consume less space.

You can now add new ROM module to your design using Xilinx Core Generator from with Xilinx Project Navigator. The detailed instructions on how to do this can also be found on the document I mentioned before. But I am kind enough to provide you this less-detailed screen shots :)



Create new source and select IP (Coregen & Architecture Wizard)



For this kind of use, a read-only Single Port Block Memeory would be enough.



You can specify some memory attributes here.



This is the most important part. You have to tick the "Load Init File" checkbox and click "Load File ..." button then choose the generated .coe file or .bw.coe file.



You can click on the "Show Coefficients" button to make sure that your file properly loaded.

Finally, click on the "Generate" button to generate your ROM module. Your ROM is now ready to use :)

I hope this helps.

Sunday, October 7, 2007

Implementing polymorphism in C

It is about my project at Chulalongkorn University again. My instructor assigned a term project in course Operating System and System Programmingto my team. We have to create a program that simulates some concepts in operating system such as
  • Process creation
  • Process termination
  • Process Scheduling
  • Interrupts
  • Interprocess Communication
  • etc.
Other requirements are the program must be able to run on at least one kind of Unix or Linux systems and the program must be coded in pure C. We used Code::Blocks + Cygwin as our development environment (how to setup Code::Blocks and Cygwin to work together?). However, we compiled and presented our program on a Mac (which is a kind of Unix).

Let's get back to our topic. In our project, a process is represented by a worm moving around the screen. I want each type of worm to move differently.

If I were coding in Java, I would create a base class, named it Worm, and derived it to create other specific classes such as LeftWorm, RightWorm, RandomWorm. This is where polymorphism comes in handy.

How can I implement such high-level object-oriented mechanism in a pure low-level C program ?

The solution is to use pointers to functions. The following code is my code sample which shows how can each animal has different behaviors.

#include <stdio.h>
#include <stdlib.h>

#define DOG 1
#define CAT 2
#define FISH 3


struct
animal{
// animal's name
char *name;
// parameters: count, target's name; return type: void
void (*bark)(int, char*);
};


// typedef a pointer to animal struct
typedef struct animal* ANIMALPTR;

// animals' behaviors
void dogbark(int count, char *target){
int
i;
for
(i = 0 ; i < count ; i++){
printf("Box! %s ", target);
}

printf("\n");
}


void
catbark(int count, char *target){
int
i;
for
(i = 0 ; i < count ; i++){
printf("Meow~ %s ", target);
}

printf("\n");
}


void
fishbark(int count, char *target){
int
i;
for
(i = 0 ; i < count ; i++){
printf("(Cannot bark) %s ", target);
}

printf("\n");
}



ANIMALPTR get_animal(int type){
ANIMALPTR ret =
(
ANIMALPTR)malloc(sizeof(struct animal));
switch
(type){
case
DOG:
ret->name = "Dog";
ret->bark = dogbark;
break
;
case
CAT:
ret->name = "Cat";
ret->bark = catbark;
break
;
case
FISH:
ret->name = "Fish";
ret->bark = fishbark;
break
;
}
}


int
main()
{

int
i;
ANIMALPTR arr[3];
arr[0] = get_animal(DOG);
arr[1] = get_animal(FISH);
arr[2] = get_animal(CAT);
for
(i = 0 ; i < 3 ; i++){
printf("Animal: %s\n", arr[i]->name);
arr[i]->bark(2,"M3rlinez");
printf("\n");
}

return
0;
}
The following is this program's output.

Animal: Dog
Box! M3rlinez Box! M3rlinez

Animal: Fish
(Cannot bark) M3rlinez (Cannot bark) M3rlinez

Animal: Cat
Meow~ M3rlinez Meow~ M3rlinez


Press ENTER to continue.

Friday, September 21, 2007

FPGA Project Completed!




This semester I has enrolled in course Hardware Synthesis Lab. It was about designing an ASIC (Application Specific Integrated Circuit) using HDL (Hardware Description Language). With HDL, the circuit designers do not have to interfere with primitive elements such as AND, OR gates. Instead, they write a module specification in a human-readable language (VHDL, Verilog) and let the synthesizer do the rests. In my class, everyone has to use Verilog with Xilinx ISE Webpack with Xilinx Spartan-3 Starter kit board.

The final project assignment is to design the classic Pong game. The video is displayed through VGA interface in 640 x 480 8 colors mode. And the users can also control their paddles using PS/2 keyboard.

It took me a week to finish this project, Here is its screen shot. (I had took this photo with my phone. The famous PrntScrn is useless in this situation :P )



Only this FPGA board and a monitor needed to run the game!
No need for CPU!




While playing



Set of in-game objects


The really hard part in this project is to make the user interface looks good while you can use only 8 colors! My lab partner, Oei, helped me a big part in choosing the color for this design. To make the screen more beautiful, I decided to put my effort into finding a way to load an image data onto my board. It took me hours reading through Xilinx documentations to find a method to load initial values for Blocked RAM on Spartan-3. I will write an entry on this later when I am free.

In conclusion, this course show me what I can get from little Spartan-3 FPGA board. And how hard it is to make a little Pong game.

I would rather code this in Java or C# and get the result in a blink if I ever need to make my own version of Pong next time o__O