Our goal for today is to create a simple tile based render engine on the fpga. Lets break down some of the things it will need.
First, what will it do? Lets go simple.
We are going to render to our 240x240 pixel screen (because thats what I have setup today).
I want a single layer of tiles where each tile is 8x8 pixels. Lets make the map big enough to render 256x256 pixels (32x32 tiles). The only fancy feature we will add is the ability to scroll the tile map and control if it wraps around or if it cuts off when you get to the end of it.
Lets do a 256 color palette where each color is a 16bit RGB565 color.
Simple enough...
First, we need some ram:
For the tile map we want a single byte per tile. This byte will simply be an index into tile graphics memory, later on we may add tile flipping or other features to the tile. Since our map is 32x32 tiles we need 1024 bytes to hold the map.
Tile graphics will be represented by 8x8 tiles where each pixel is represented by a single byte which maps to a color in the palette. Since we can only address 256 tiles our tile graphics memory will be 8x8 * 256 = 16KB.
The palette is pretty easy...just 256 16-bit entries for 512 bytes of data.
Finally, We need a single array of ram to hold a rendered line. Lets render in RGB565 format (5 bits red, 6 bits green, 5 bits blue). Lets go ahead and make this line 256 pixesl wide because powers of two make life much easier on fpga. We could have done 240 to save a bit of space. Each pixel is 2 bytes (RGB565) so we need 512 bytes of data for this line.
That should be it for graphics ram.
Next, we will need and SPI implementation. Sure, we could probably just take one off the shelf or from an IP library but I have a little secret...SPI is just a shift register...we got this.
We are also going to want two GPIOs, one to indicate the frame is done (vertical blank interrupt) and one to indicate a line is done (horizontal interrupt). Both of these will be one way from FPGA to MCU. To keep things simple we will ensure we wait long enough each line to ensure the MCU has time to copy it all.
Finally, we just need an x and y counter to loop through all the pixels on the screen...this will address a tile in the tile map, use that to grab the right tile graphics from the tile memory and then use those graphics to find the right color in the pallet and then finally stuff that into the array we made to hold the display line.
We will come back and figure out how to make ti scroll and wrap and all that jaz in a bit.
And that sums up what we are going to be doing. The next part will be setting up the FPGA tools and hooking them up to our retro watch so we can get to developing!