SkillAgentSearch skills...

FmcPGA

A pseudo Minecraft game running on Artix-7 FPGA in VHDL. Also the final project for SUSTech EE332-Digital-System-Designing.

Install / Use

/learn @Gralerfics/FmcPGA
About this skill

Quality Score

0/100

Category

Design

Supported Platforms

Claude Code
Cursor

README

FmcPGA - Pipelined Minecraft-like 3D Game Rendering

<!-- [![GitHub license](https://img.shields.io/github/license/gralerfics/FmcPGA.svg)](https://github.com/gralerfics/FmcPGA/blob/master/LICENSE) [![GitHub forks](https://img.shields.io/github/forks/gralerfics/FmcPGA.svg)](https://github.com/gralerfics/FmcPGA/network) [![GitHub stars](https://img.shields.io/github/stars/gralerfics/FmcPGA.svg)](https://github.com/gralerfics/FmcPGA/stargazers) --> <!-- Wang Zhuoyang$^1$, Shu Zihe$^2$ --> <!-- <font size=2>$^1$12112907, Department of Electrical and Electronic Engineering, SUSTech. Email: glverfer@outlook.com</font> <font size=2>$^2$12111727, Department of Electrical and Electronic Engineering, SUSTech. Email: 12111727@mail.sustech.edu.cn</font> -->

Introduction

This project is a simple 3D voxel game renderer built entirely using VHDL, based on a pipelined architecture. Here is a screenshot of the final result in action:

<div align="center"><img src="doc/img/items.jpg" /></div>

Inspiration

VHDL, as a hardware description language, is well-suited for handling computationally intensive parallel problems, which aligns perfectly with the requirements of three-dimensional rendering applications.

Related Work

After conducting a preliminary search, it was found that there are few projects directly implementing 3D rendering on FPGA. Furthermore, those projects that do exist are relatively simple and may encounter performance issues. Some projects have achieved true rasterization rendering; however, they are not open-source, and the specific implementation details remain unclear. Here are a few typical related projects listed below:

  1. 3D Game Prototype on an FPGA, a pseudo 3d game demo, not a real 3D engine.
<div align="center"><img src="doc/img/pseudo3d.png" height="250" /></div>
  1. 首次在FPGA上实现3D填色图像生成, a mesh renderer, and is not open-sourced.
<div align="center"><img src="doc/img/teapot.png" height="250" /></div>
  1. FPGA and ARM based 3D solid mesh renderer, a solid mesh renderer, but seems to be not in pure hardware implementation (with ARM cores).
<div align="center"><img src="doc/img/model.png" height="250" /></div>
  1. 3D engine on FPGA home made, a nice 3D engine.
<div align="center"><img src="doc/img/3dengine.png" height="250" /></div>
  1. nickmqb/fpga_craft, a very wonderful and open-sourced Minecraft clone, but is implemented in the author's own HDL, and is a entire system including CPU and GPU, which can not be taken as our reference.
<div align="center"><img src="doc/img/fpgacraft.png" height="250" /></div>
  1. ...... (more examples are omitted)

According to the course requirements, we aim to construct the project using pure HDL (Hardware Description Language). In order to ensure the completeness of the project, we also desire to have a comprehensive scene and a user interface for interaction, rather than just a test program that lacks the essence of a game. Therefore, we have ultimately chosen to utilize VHDL to build a game resembling the classic sandbox game Minecraft on FPGA.

It is worth noticing that we did not reference or draw inspiration from any open-source repositories, and we solely relied on the knowledge taught in the classroom for development. We independently contemplated and wrote every single detail.

Features

We have implemented the following features:

  1. Storage and rendering mapping for 24 types of blocks and 32 types of textures.
  2. Free movement and perspective adjustment for the player character, with adjustable spherical field of view.
  3. Block switching, placement, and destruction.
  4. Scene rendering and sky background color.
  5. Alpha blending for transparent objects.
  6. Control using a PS2 controller and VGA output.
  7. ...... (more features are omitted)

Key Issues

During the development process, several key issues were encountered. We briefly describe the solutions below, with detailed explanations provided in the subsequent sections:

  1. Cross-clock domain issue between the VGA display module and rendering module (Solution: implementing dual-buffered frame memory).
  2. Enhancing rendering frame rate (Solution: designing a multi-level pipelined architecture).
  3. Managing RAM access among various modules (Solution: employing pipeline operations and prioritizing on-demand configuration read/write).
  4. Handling floating-point calculations in the rendering computation (Solution: adopting fixed-point arithmetic approach and performing all calculations using integer operations).
  5. Reducing resource consumption (Solution: employing pipeline design and globally reducing the number of integer signal bits).
  6. ...... (more issues are omitted)

Development Environment and Toolchains

We utilized Vivado 2022.2 on Ubuntu 20.04 as the synthesis and implementation tool, along with ghdl, ModelSim, and the built-in tools of Vivado for simulation. Our primary development language was VHDL 2008 (excluding the Verilog part in clock IP cores and some other where).

Overview

System Architecture

First, let's present the overall structure of the system. Due to its complexity, a more abstract block diagram is used for illustration. This diagram represents the RTL (Register Transfer Level) block diagram of the system, but it may not necessarily match the module divisions in the code. The code modules are further broken down into smaller components. Here is the diagram:

<div align="center"><img src="doc/img/arch.jpg" /></div>

From the diagram, several important components can be identified. Here's a brief introduction to them, with detailed explanations provided in the following sections:

  1. First, we have the Rendering Pipeline and its associated input/output processing structures. It is primarily responsible for performing high-speed collision detection between the line of sight and objects, as well as conducting color calculations for rendering.
  2. Above that, we have the Player State Manager and its associated circuits. It is responsible for storing the player's position, perspective, currently selected items, and other states. It receives input from input devices, provides player information to external components, and handles player interactions with the map, such as block destruction and placement.
  3. On the right side, we have the graphics display section, centered around the Display Control module. It receives color calculation outputs from the pipeline and provides the desired color values to the VGA Controller. The dual-buffered structure and cache swapping operations ensure isolation of RAM read/write operations to prevent conflicts.
  4. Other scattered RAM and ROM modules are used to store map data, textures, block information, and texture mappings. They are connected to other modules as needed, eliminating the need for further elaboration.

I/O Ports

Regarding the I/O Ports of the Top Module, it mainly consists of the following:

  1. A 100MHz clock input, labeled as clk_sys.
  2. A reset signal, labeled as rst.
  3. Button inputs for front, back, left, right, up, and down, denoted as btn_{front/back/left/right/up/down}_in (unused when switching to controller input).
  4. SPI communication lines for the gamepad, including spi_cs (chip select), spi_clk (clock), spi_mosi (master output, slave input), and spi_miso (master input, slave output).
  5. A VGA output structure, represented by the structure vgaout.
  6. Debug outputs for a seven-segment display, including anodes_n (anode control) and segs_n (segment control).

Architecture

Below, we will provide detailed explanations for each of the components mentioned earlier in the introduction, including the principles, timing requirements, and design of each component.

Rendering Pipeline

Pipeline

As mentioned earlier, the main functions of the Rendering Pipeline are to calculate the path of ray traversal and compute color values.

Before delving into the detailed explanation, it is necessary to provide a brief introduction to the ray marching algorithm used in this project for rendering.

To render a three-dimensional scene on a two-dimensional plane, a common approach is to assume a point where the viewer's eye is located and connect the eye to each pixel on the screen with a ray called a "ray". Clearly, for each ray emitted from a pixel, the color of the object it intersects as it travels backward is the color that should be displayed at that point on the screen, which is known as simple perspective projection. This involves calculating the intersection of each ray with various objects in the scene. Implementing this using traditional rasterization methods can be complex in terms of hardware implementation.

Taking into consideration the characteristics of the Minecraft game, where the scene is composed of blocks and each face is parallel to the coordinate axes, and the rays pass through a certain number of blocks during their traversal, it becomes simpler and more straightforward compared to calculating each face separately. Therefore, we employ the so-called "ray marching" algorithm. Each ray starts from the block where the viewer's eye is located, and at each step, we only need to calculate which direction (x, y, or z) the ray will intersect with a block face first based on its current direction. This allows us to determine which block the ray enters after passing through the current block. Additionally, if a block is not an air block, we can obtain the coordinates of the hit point and perform texture mapping to calculate the corresponding color value, thereby concluding the propagation of that ray. Take the situation in 2-D space as an example:

<div align="cen

Related Skills

View on GitHub
GitHub Stars92
CategoryDesign
Updated1mo ago
Forks5

Languages

VHDL

Security Score

95/100

Audited on Mar 6, 2026

No findings