After managing to get my graphics controller working at a mediocre resolution of 100×75, I wanted to squeeze as much performance out of this chip as possible! Unfortunately, due to memory constraints, this meant rewriting the VGA controller to work at a different resolution. The original controller was running at a resolution of 800×600, which when divided by 8 gives us the 100×75 pixel resolution with each 100×75 macropixel consisting of 8x 800×600 pixels. I’m using power of two resolution divisions as this allows me to calculate the memory addresses through only two shifts and a multiply, as opposed to 2 shifts and 3 multiplies (along with much more logic space…). Therefore, the next logical size up will be 4x sized macropixels, meaning a total resolution of 200×150. All seemed great after I changed the memory widths and hit compile. Disaster! Turns out, my FPGA only contains 30x M9K memory blocks whereas for a resolution of 200×150 (at 8bpp), would’ve required 32x M9K blocks! I can’t help but feel a little gutted that only two M9K blocks were holding me back from the prime resolution of 200×150 pixels.
I then reattached my thinking hat and thought of other methods of squeezing out the best performance I could from this chip. If 200×150 was the next step from 100×75 for a master resolution of 800×600, why not change to a different master resolution and subdivide that? And so that is what I did. I’ve now rewritten the VGA controller to work at 640×480 though I need to test how temperamental it is in the long term. Since my master clock is 48MHz, the best I can achieve with the PLL is a pixel clock of either 25.2MHz (supposed to be 25.175MHz) or 31.5MHz. Of these two, the 25.175MHz clock is the industry standard, however since I can actually properly synthesize the 31.5MHz clock, I’ll be using this. This will give a refresh rate of either 73Hz in VGA mode of 75Hz in VESA mode.
Now that I’m running my monitor at 640×480, I can group the pixels into 4×4 macropixels (640×480/4 = 160×120) while also storing the whole framebuffer in my onboard dual port SRAM! This is pretty much the best resolution that I can achieve in my setup without the use of external RAM though even this small increase in resolution (1.6:1.33..), video playback has reduced to a sloooooow 6.6fps.
Oh yeh, it turns out I had a small error in my original block diagram file where the memory clock is meant to be the same as the shift register clock. This was causing erratic pixel errors at high write rates.
Rerouting the memory clock
Keep tuned for more updates!