So, after quite some I’ve finally started work on a project that I’ve wanted to do for a long time. I will start working on the architecture for a very simple GPU. The posts that I will be uploading will be both a collection of learning experiences as well as code for anyone that wants to replicate the effort.
I should note for that I in no way intend to duplicate the architecture of the latest GPU units. This is merely an exploratory journey to achieve something that I consider a personal goal. I will no undoubtedly choose the wrong block components or design philosophies that will lead me to wrong paths. The end result might be something that takes minutes or to process a frame and look horrible and I think that’s ok. This is an attempt to see what can one person reasonably achieve within a year. I will start with a completely blank page and go from there. As much as possible, I will follow these rules to make things interesting:
- I cannot use IP cores to do any of the main GPU operations (Things not related to the GPU like VDMAs and video interfaces are allowed)
- I will not copy any VHDL/Verilog code from open source locations
- I will not explicitly choose any architectures that match modern GPUs.
The idea is tostart with a blank page and see if my end result looks similar to what a GPU looks like. So, after this long winded explanation, let’s start!
I envision the project will be broken up into a few steps. First off, I will want to get the tools up and working for an FPGA+ARM board and I want to be able to draw a solid color onto the screen, or a simple gradient:
Next off, I will generate a very simple scene with some vertices and attempt to display them on screen:
This step will get things rolling since I will have to figure out how to map a collection of 3d points to a 2d representation, mixing in the virtual camera, doing field of view projections, etc. Next off, I will make things more interesting by adding in connections between the vertices and attempt a wireframe render:
The good part comes after this, when I’ll have to fill in the faces and figure out which need to be drawn on top of which:
This will also likely involve adding in some primitive lighting into the mix. And, if all works well, I might even try to add some texturing:
This is all completely speculative. I don’t even know if I will be able to implement the solid colored version, let alone the shaded version, but I’ll aim pretty high.
The system block design for what I will be working on will look like this:
The idea is that the CPU will write a description of the scene, the GPU will create the 2d representation and store it in a framebuffer, a Video DMA block will pull the data from the framebuffer 60 times per second to generate a VGA video stream.
I will be developing things on a Zynq Zebo board. Why? Because Zynq’s are awesome. You get a dual core ARM processor bolted on top of the FPGA fabric of an Artix-7 FPGA with all the tools tightly integrated and things just work. I looked for a cheap eval board that has enough FPGA fabric and a VGA port. Why not HDMI? Because HDMI causes lots of headaches. You have to configure serializers, which means that you require a processor to configure the external chip before you can even see a blank screen. So yes, this will be archaic, but I don’t want to work hours on end just to get a fancy video port working. VGA doesn’t require any software to work and is 10 times simpler to debug.
So now, we’re off to buy a Zebo board! The next post will go up once I receive the board.