FPGA Polyphonic Music Synthesizer

Verilog FPGA Digital Design Audio DSP VGA
Report overview for an FPGA polyphonic music synthesizer project

Built for Stanford EE108, this Verilog music player reads songs from ROM and synthesizes polyphonic audio with weighted harmonics, ADSR dynamics, echo, stereo panning, and a past/present/future note display.

At a Glance

Course
Stanford EE108 final project
Team
Taylor Tam, Benji Warburton, Danica Sun
Core Features
3-voice chords, harmonics, ADSR, echo, stereo, note display
Tools
Verilog, Vivado, FPGA audio pipeline, VGA display logic

System Overview

The design is organized around a ROM-driven playback path. An MCU-side controller selects a song, song_reader steps through note data in song_rom, and the audio pipeline synthesizes each note before passing the result to the codec. In parallel, a VGA display path renders the recent notes, active notes, and upcoming notes so the interface mirrors the playback state.

Audio Pipeline

Waveform verification results for the FPGA music synthesizer modules

Verification

The testbench suite covered chord generation, harmonics, dynamics, echo, note display, and stereo effects. The submitted waveforms verify behaviors like third-voice suppression on very low notes, harmonic-region switching, sample-tick-driven envelope updates, signed echo saturation, and distinct left/right stereo outputs.

Timing and Design Tradeoffs

According to the final report, the 100 MHz logic, 25 MHz display, and 48 MHz codec domains each met intra-domain timing. Remaining violations were isolated to unsynchronized 100 MHz to 25 MHz crossings, which made clock-domain behavior the main systems risk rather than any single synthesis block. The project also forced careful overflow handling in the chord mixer and echo stage so parallel features did not degrade audio quality.

Why This Project Matters

This was a good end-to-end digital systems project: ROM control, signal synthesis, display logic, verification, and timing all had to work together. The most useful takeaway was learning to treat synchronization, sample timing, and interface consistency as part of the product itself, not as cleanup after the main functionality works.

Back to Projects