Home
Welcome
Information


FPGA projects
Basic
Music box
LED displays
Pong game
R/C servos
Text LCD module
Quadrature decoder
PWM and one-bit DAC
Debouncer
Crossing clock domains
External contributions

Interfaces
RS-232
JTAG
I2C
EPP
SPI
PCI
PCI Express
10BASE-T

Advanced
Digital oscilloscope
Graphic LCD panel
Direct Digital Synthesis
CNC steppers
Spoc CPU core

Hands-on
A simple oscilloscope


FPGA introduction
What are FPGAs?
How FPGAs work
Internal RAM
FPGA pins
Clocks and global lines
Download cables
Configuration
Learn more

FPGA software
Design software
Pin assignment
Design-entry/HDL
Simulation/HDL
Synthesis and P&R

FPGA electronic
SMD technology
Crystals and oscillators

HDL info
HDL tutorials
Verilog tips
VHDL tips

Quick-start guides
ISE
Quartus

Site
News
FPGA links
HDL tutorials
Forum


Music box - part 1

Simple beep
FPGAs can easily implement binary counters. Let's start with a 16-bits counter.
Using a 25MHz clock, we "divide the clock" using a 16 bits counter that counts from 0 to 65535 (65536 different values). The highest bit of the counter toggles at a frequency of 25000000/65536=381Hz.

The Verilog HDL code looks like this:

module music(clk, speaker);
input clk;
output speaker;

// Binary counter, 16-bits wide
reg [15:0] counter;
always @(posedge clk) counter <= counter+1;

// Use the highest bit of the counter (MSB) to drive the speaker
assign speaker = counter[15];
endmodule

In more details, "counter[0]" toggles at 12.5MHz, "counter[1]" at 6.125MHz, and so on.
Since we use the MSB (bit 15) of the counter to drive the output, a nice 381Hz square signal comes out of the "speaker" output.
"A" note (440Hz)
Ok, better than a random frequency, why not try to get a 440Hz signal. That's the frequency of the "A" note.

Instead of dividing 25MHz by 65536, we need to divide by 56818. Here we go.

module music(clk, speaker);
input clk;
output speaker;

reg [15:0] counter;
always @(posedge clk) if(counter==56817) counter <= 0; else counter <= counter+1;

assign speaker = counter[15];
endmodule

There is a problem though. The frequency is 440Hz, as expected, but the output duty cycle is not 50% anymore. The low level goes from counter=0 to counter=32767 (when bit 15 of counter is low) and then high level from 32768 to 56817. That gives us "speaker" being high only 42% of the time.

The easiest way to get a 50% duty cycle is to add a stage that divides the output by 2. So first we divide by 28409 (instead of 56818) and then by 2.

module music(clk, speaker);
input clk;
output speaker;

reg [14:0] counter;
always @(posedge clk) if(counter==28408) counter <= 0; else counter <= counter+1;

reg speaker;
always @(posedge clk) if(counter==28408) speaker <= ~speaker;
endmodule
Adding a parameter
Here's essentially the same code. A new parameter named "clkdivider" was added, and the counter was changed into a "count-down" counter - just a matter of preference.

module music(clk, speaker);
input clk;
output speaker;
parameter clkdivider = 25000000/440/2;

reg [14:0] counter;
always @(posedge clk) if(counter==0) counter <= clkdivider-1; else counter <= counter-1;

reg speaker;
always @(posedge clk) if(counter==0) speaker <= ~speaker;
endmodule


>>> NEXT: Music box - part 2 >>>



This page was last updated on July 05 2010.