Skip to content

Latest commit

 

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 

Repository files navigation

Quack Quest

A hardware maze game implemented in Verilog on the DE1-SoC FPGA, combining FSM-based control, PS/2 keyboard input, VGA rendering, ROM-based collision detection, and countdown/score logic.

Verilog · DE1-SoC · Cyclone V FPGA · RTL Design · Finite-State Machine · VGA · PS/2 · On-Chip ROM

Quack Quest maze running on a VGA display

Project Overview

Quack Quest is a maze-navigation game implemented directly in FPGA logic. The player uses a PS/2 keyboard to move through a VGA-rendered maze while the hardware coordinates movement, collision handling, drawing, timing, and end-game behaviour.

The design separates control from datapath logic. A 16-state finite-state machine sequences each movement through clear, move, collision-check, redraw, delay, and end-game states, while the datapath tracks the player's coordinates and interprets keyboard scan codes.

What It Does

  • Keyboard-controlled movement: use W/A/S/D input from a PS/2 keyboard to move through the maze.
  • FSM-driven game flow: sequence movement, clearing, drawing, collision handling, delays, and end-game behaviour in hardware.
  • ROM-based collision detection: inspect the maze's stored pixel data before accepting movement into the next position.
  • Wall penalties: reverse invalid movement and deduct 5 from the countdown whenever the player hits a wall.
  • VGA maze rendering: display a 160×120 game surface initialized from maze image data and update the player's position as the game runs.
  • Goal and timeout handling: enter the end-game state when the goal region is reached or the countdown expires.

System Architecture

┌─────────────────────────────────────────────────────────────────────────┐
│                    DE1-SoC — Cyclone V FPGA                             │
│                                                                         │
│   ┌────────────────┐        ┌─────────────────────┐                     │
│   │  PS/2 Keyboard │───────►│   PS/2 Input Path   │                     │
│   │    W/A/S/D     │        │ Scan-Code Capture   │                     │
│   └────────────────┘        └──────────┬──────────┘                     │
│                                        │                                │
│                                        ▼                                │
│                            ┌────────────────────────┐                   │
│   ┌────────────────┐       │      Game Logic        │                   │
│   │    Maze ROM    │──────►│                        │                   │
│   │ 160×120, 3-bit │       │ • 16-State Control FSM │                   │
│   │   Pixel Data   │       │ • Movement Datapath    │                   │
│   └────────────────┘       │ • Collision Handling   │                   │
│                            │ • End-Game Control     │                   │
│                            └───────┬────────┬───────┘                   │
│                                    │        │                           │
│                   ┌────────────────┘        └─────────────┐             │
│                   ▼                                       ▼             │
│          ┌──────────────────┐                     ┌────────────────┐    │
│          │ Countdown /      │                     │ VGA Draw/Clear │    │
│          │ Collision Penalty│                     │     Logic      │    │
│          └────────┬─────────┘                     └───────┬────────┘    │
│                   │                                       │             │
│                   ▼                                       ▼             │
│          ┌──────────────────┐                     ┌────────────────┐    │
│          │ Seven-Segment    │                     │  VGA Adapter   │    │
│          │ Score / Status   │                     │  + Framebuffer │    │
│          └──────────────────┘                     └───────┬────────┘    │
│                                                           │             │
│                                                           ▼             │
│                                                      VGA Monitor        │
└─────────────────────────────────────────────────────────────────────────┘

Engineering Highlights

16-State Hardware Control Path

The central game controller is implemented as a 16-state FSM. Separate states handle idle behaviour, clearing the player's previous position, movement in each direction, collision recovery, drawing, movement delay, and the end-game condition.

This structure keeps the sequencing explicit: a movement request first clears the previous pixel, updates the position, checks the destination, rolls the movement back if a collision occurred, redraws the player, and then returns to the idle state after a rate-divided delay.

ROM-Based Collision and Goal Detection

The maze is stored as 3-bit pixel data in a 19,200-word ROM corresponding to the 160×120 game surface. Collision logic derives a memory address from the player's current coordinates and instantiates four maze-ROM lookup paths for the positions three pixels above, below, left, and right.

The FSM interprets the returned pixel value before completing a move. A wall value routes execution through a collision state, while the designated goal value transitions directly to the end-game state. Because the collision system uses the original maze data rather than the modified VGA framebuffer, player drawing does not overwrite the information used to determine where movement is valid.

VGA Rendering

The game uses a VGA adapter configured for a 160×120 logical resolution with one bit per RGB channel. The framebuffer is initialized from mazeL1new.mif, giving the game its maze background immediately after the FPGA is programmed.

The player is rendered as a white pixel. During movement, the previous location is cleared and the new coordinate is drawn, allowing the game logic to update only the player's position instead of redrawing the complete maze each time.

PS/2 Keyboard Control

Keyboard input is captured through an adapted PS/2 input path. The design keeps the most recent scan-code bytes and maps the standard W/A/S/D scan codes to up, left, down, and right movement requests.

Release-code handling prevents a released key from being interpreted as a new movement command, while the decoded keyboard data is also exposed on seven-segment displays for hardware-level visibility during operation.

Countdown and Collision Penalty

A dedicated down-counter is initialized to 90 and driven by rate-divider logic. A collision event subtracts 5 from the remaining count, coupling the maze's collision behaviour directly to the game's timing logic.

The controller enters the end-game state when the countdown reaches zero or when the goal is detected. A custom seven-segment decoder is used for the game's score/status output.

Quack Quest score displayed on the DE1-SoC seven-segment display


Hardware & Interfaces

Component Role
DE1-SoC Target FPGA development platform
Cyclone V SoC FPGA FPGA device targeted by the Quartus project
50 MHz board clock Main clock source for game, input, rendering, and rate-divider logic
PS/2 keyboard interface W/A/S/D player control
VGA output Displays the maze and player position
160×120 framebuffer Stores the rendered game surface
Maze ROM / MIF data Stores the original 3-bit maze pixels used for display and collision lookup
Seven-segment displays Score/status and keyboard scan-code visibility
Board keys / switches Reset and restart control

Implementation Structure

Module Responsibility
mazefinal.v Top-level integration of game logic, countdown, VGA rendering, PS/2 I/O, and seven-segment output
gameLogic.v 16-state control FSM, movement datapath, scan-code interpretation, collision handling, and end-game logic
drawBox.v Player clear/draw control and VGA adapter configuration
downCounter.v Countdown, rate-divider logic, collision penalty, and custom score decoder
mazeL1new.mif / mazeL1new.v 160×120 maze image data and ROM used by the collision system
PS2_keyboard.v / PS2_Controller.v Adapted/reference PS/2 scan-code capture and keyboard communication
VGA support modules Framebuffer, address translation, timing control, and VGA clock generation
Hexadecimal_To_Seven_Segment.v Converts captured keyboard data for seven-segment display

The project-specific RTL coordinates the control FSM, datapath, timer, collision behaviour, and rendering path while integrating course/reference PS/2 and VGA support modules.


Engineering Takeaways

  • Designed a 16-state RTL control path to coordinate movement, rendering, collision recovery, and end-game behaviour.
  • Implemented pixel-data-driven collision detection using parallel lookups into an initialized on-chip maze ROM.
  • Integrated PS/2 keyboard and VGA interfaces into a hardware game running on the DE1-SoC Cyclone V FPGA.
  • Coordinated movement rollback, collision penalties, countdown logic, and framebuffer updates across multiple Verilog modules.
  • Structured the design around separate control and datapath logic, making hardware sequencing and state transitions explicit.

Reference Components

The PS/2 controller and VGA adapter support files are based on course/reference components. They are integrated and, where applicable, adapted for Quack Quest; the project-specific game control, datapath, collision behaviour, countdown logic, rendering control, and top-level integration are implemented in the project's own Verilog modules.


Source Availability

This project was completed as part of University of Toronto coursework. To respect academic-integrity requirements, the implementation source code and course-specific files are not publicly available.

This repository is intended as a technical showcase of the system architecture, FPGA implementation approach, and engineering decisions.

About

Hardware maze game built in Verilog on the DE1-SoC FPGA, featuring FSM-based control, PS/2 input, VGA rendering, and ROM-based collision detection.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors