We designed a RISC-V CPU from scratch, successfully ported 'DOOM,' and achieved a maximum frame rate of 20 FPS.



Student developer Armaan Gomez and his team successfully ran the 1993 FPS 'DOOM' on a custom CPU they designed from the logic gate stage. Initially, it could only render at 0.7 FPS, but through repeated improvements to the CPU and memory, they eventually sped it up to a level where it could be played at 15-20 FPS.

Running DOOM on our Custom CPU and Going Viral | Armaan Gomes

https://armaangomes.com/blogs/doom/

DOOM is a first-person shooter released by id Software in 1993 that had a significant influence on subsequent games. Because its source code is publicly available and it can run on relatively limited computing resources, it has been ported to various devices such as tractors , pregnancy test kits , and ultrasound scanners .

Gomez and his colleagues designed a CPU based on the open instruction set 'RISC-V' from the logic gate level and implemented it on an FPGA. RISC-V is a public specification that defines what instructions a CPU processes, and the CPU developed supports the basic specification 'RV32I' which performs 32-bit integer arithmetic. They had previously succeeded in running programs such as 'Pong' and programs that draw the Mandelbrot set on their CPU, but DOOM was the first time they had run a commercially available full-fledged game.

The first major problem in running DOOM was memory capacity. While FPGAs have high-speed read/write memory, its capacity is less than 1MB, which is insufficient to store the approximately 14MB of DOOM game data. Therefore, the development team connected a large-capacity DDR3 memory module to the CPU.

However, while DDR3 has a large capacity, it takes time to read data, which would cause the CPU to repeatedly wait for processing. To reduce this waiting time, a cache was added to temporarily store frequently used data in high-speed internal memory. Instructions executed by the CPU and data used in the game are stored in separate caches, allowing necessary information to be retrieved as quickly as possible. In addition, a mechanism was adopted in the CPU to process multiple instructions in parallel, albeit in small increments.

After connecting the DDR3 memory, a test was also conducted to load and display video on the screen. It was confirmed that video data could be continuously read from the large-capacity external memory and output to the screen.


A dedicated system was also required for screen display and keyboard operation. The video output circuit is connected to the HDMI terminal, and the keyboard input uses a system where signals are sent from the laptop.

For the DOOM port, they used ' doomgeneric ,' which was designed to run easily on various devices. Even so, they encountered numerous problems with screen display and file loading, and it was necessary to investigate each issue to determine whether the problem lay with DOOM or with the custom-built CPU.

When actually running DOOM, we found bugs such as the CPU repeatedly stopping after processing the same task, or executing instructions in the wrong location. Additionally, the game's data saving mechanism has been found to incorrectly overwrite instructions that are currently being executed.



Because DOOM as a whole is extremely complex, the development team used small test programs to verify CPU operation. As a result, they identified several bugs that had not been found in the previous simpler programs and gradually fixed them.

Another problem arose where DOOM would run in a PC simulation but crash on the actual FPGA. Investigation revealed that the game assumed the memory would contain zeros before use, but irregular values remained in the actual memory. The program was corrected, and the game successfully launched.



When DOOM first started running, the frame rate was about 0.7 FPS, and the screen was switching every few seconds.


By increasing the CPU's operating speed and reducing unnecessary memory access, the frame rate was increased to approximately 2.5 FPS. Furthermore, by adding the 'Zmmul' extension specification, which supports RISC-V multiplication instructions, and enabling multiplication to be processed directly by the CPU, the speed was improved to approximately 3.5 FPS.


Furthermore, after reviewing the screen display method and cache processing, the frame rate reached approximately 6.7 FPS. With compiler optimizations enabled to automatically optimize the program, DOOM now runs at 15-20 FPS. While this is certainly not as smooth as the latest game consoles, it's at a level where it's actually playable on a custom-built CPU.

The following is footage of DOOM being played at 20 FPS.


Gomez says that through this development, he learned not only about CPU and memory design, but also how to systematically investigate problems in complex systems. He also plans to further speed up the CPU to aim for 30 FPS, and has outlined plans to build his own GPU for video processing to run 'Quake II'.

Gomez explained that while they actively used AI in development, it didn't automatically complete the CPU or DOOM port. While AI was helpful as a tool for creating code, suggesting corrections, and investigating errors, it sometimes returned incorrect answers. Therefore, knowledge of CPU mechanics and low-level programming was essential to determine if the suggestions were correct and to verify them on actual hardware.

in Video,   Hardware,   Software,   Game, Posted by log1i_yk