Skip to content

Lab 3: Music Player
Part D: FPGA Prototype V2

Lab 3 will give you experience designing, implementing, testing, and prototyping combinational and sequential logic using the Verilog hardware description language. The lab will continue to leverage concepts from Topic 2: Combinational Logic, Topic 3: Boolean Algebra, and Topic 4: Combinational Building Blocks but will also leverage concepts from Topic 6: Sequential Logic, Topic 7: Finite-State Machines, and Topic 8: Sequential Building Blocks. More specifically, the lab will give students experience with: latches, flip-flops, and registers; Moore and Mealy FSMs; and counters. The lab will continue to reinforce three key abstraction principles: modularity, hierarchy, and regularity.

You will be implementing a music player that takes as input a song selection (via the switches) and a start song signal (via a push button). The music player will then play the chosen song by generating a square wave at appropriate note frequencies suitable for use with a piezoelectric buzzer. An idle signal is displayed using an LED so that the user knows when the player is ready to play a new song. The music player will make use of the adders and muxes from Lab 2. The song selection and the current note are both displayed using seven-segment displays from Lab 1. This lab also serves as a transition from lower-level gate-level (GL) modeling to higher-level register-transfer-level (RTL) modeling. Some of parts of your design will use explicit GL modeling, while other parts of your design will use RTL modeling. Students will have a chance to appreciate how RTL modeling can improve productivity but with less control over the final hardware implementation. The lab includes five parts:

  • Part A: Counter and Note Player

    • Due 10/19 @ 11:59pm via GitHub
    • Students should work on Part A before, during, and after your assigned lab section during the week of 10/6
    • Pre-lab survey on Canvas is (roughly) due by end of lab section during the week of 10/6
  • Part B: Multi-Note and Music Player

    • Due 10/26 @ 11:59pm via GitHub
    • Plan to work on Part B after fall break and during the week of 10/20
  • Part C: FPGA Prototype v1

    • Due week of 10/20 during assigned lab section
    • This part will focus on prototyping the code developed in Part A
    • Even though completed with a partner, every student must turn in their own paper check-off sheet in their lab section!
  • Part D: FPGA Prototype v2

    • Due week of 10/27 during assigned lab section
    • This part will focus on prototyping the code developed in Part B
    • Even though completed with a partner, every student must turn in their own paper check-off sheet in their lab section!
  • Part E: Report

    • Due week of 10/27, three days after lab section @ 11:59pm via Canvas
    • Post-lab survey on Canvas is due at the same time as the report

This handout assumes that you have read and understand the course tutorials and that you have attended the discussion sections. This handout assumes you have successfully completed Parts A-C, meaning your counter, note player, multi-note player, and music player are all working in simulation and your counter worked as an FPGA prototype.

What do we do if Part B is not done?

We assume students have completed Part B. If your music player is not working and passing all of the tests but your multi-note player is not working, we do not recommend trying to get the music player working first. Instead first show a TA your multi-note passing the tests in Task 2 and then go ahead and focus on Lab Check-Off Tasks3. Once those are done you can go back and try to get your music player working and thus complete Lab Check-Off Tasks 2 and 4+. If your multi-note player is also not working, then you must focus on getting your multi-note player working before you can complete anything in Part D.

Here are the steps to get started:

  • Step 1. Find your lab partner
  • Step 2. Find a free workstation
  • Step 3. Ask the TAs for a lab check-off sheet (each student needs their own check-off sheet)

For each lab report task you must take some notes, save a screenshot, and/or record some data for your lab report. Students can start working on their lab report during their lab session, but will likely need to continue working on their lab report after the lab session. The lab report is due on Canvas at 11:59pm three days after your assigned lab section.

For each lab check-off task you must raise your hand and have a TA come to check-off your work. The TA will ask you the questions included as part of the lab check-off task and the assess your understanding using the following rubric: mastery; accomplished; emerging; beginning. If the TA and students together feel the students have not mastered the lab check-off task, the students are encouraged to take a few minutes and try again.

What do we do if the TAs are busy?

Students must maintain a sense of urgency throughout the three hour lab section. When you get to a lab check-off task, raise your hand for 2-3 minutes. If no TA is available you must keep going; if nothing else read ahead and make a plan for the next section of the lab handout. If you do nothing and wait 20-30mins with your hand raised for a TA then you will not be able to finish all of Part D. You must be strategic. Keep moving through the handout and bring over a TA when they are free to possibly look at multiple lab check-off tasks. If you are truly stuck and no TA is available, ask your neighbors. We need to all work together to make sure every student can complete Part D. There are no extensions and students cannot complete Part D at any other time except during their assigned lab section.

Lab Check-Off Task 1: Setup Lab Kit

The TAs will pass out an ECE 2300 Lab Kit to each group. The TAs will record the kit number on your check-off sheet. For this lab, you will receive the FPGA board, a USB cable, and a component box with a piezo buzzer and some wires. Use the USB cable to plug the FPGA board into the workstation.

1. Simulate the Mulit-Note Player and Music Player

Before starting to work on an FPGA prototype, you must make sure you have a working Verilog hardware design that has been thoroughly tested in simulation. One student should start VS Code on the workstation, log into the ecelinux servers, source the setup script, and make sure their individual remote repository is up to date.

% source setup-ece2300.sh
% cd ${HOME}/ece2300/groupXX
% git pull
% tree

Where XX is your group number. Now run all of the tests from a clean build to ensure your design is fully functional.

% cd ${HOME}/ece2300/groupXX
% trash build
% mkdir build
% cd build
% ../configure
% make check

We now need to get the files for your design from ecelinux onto the workstation. This requires multiple steps.

  • Step 1. Click Microsoft Edge on the desktop to open a web-browser on the workstation to log into GitHub and then find your repository

  • Step 2. Start PowerShell by clicking the Start menu then searching for Windows PowerShell

  • Step 3. Use the following command to change to your home directory on the workstation in the lab (where netid is your Cornell NetID)

% cd C:\Users\netid
  • Step 4. Clone your repo onto the workstation by using this command in PowerShell (where netid is your Cornell NetID, notice we are using https!):
% git clone https://github.com/cornell-ece2300/groupXX
  • Step 5. In the Connect to GitHub pop-up, click Sign in with your browser

  • Step 6. You may be asked for your GitHub username again and you may be asked to authorize the Git Credential Manager; click authorize git-ecosystem

  • Step 7. Verify that you have successfully cloned your repo by changing into your repo and using tree on the workstation:

% cd groupXX
% tree

Lab Check-Off Task 2: Verify Design in Simulation

Show a TA that your hardware designs are passing all of test benches on ecelinux. If your multi-note player is working but the music player is not working, then the TA will tentatively mark this task with a 3, but you can come back and try to get the music player working at the end of the lab to potentially increase your score to a 5. You cannot continue to the next tasks unless you have at least showed your multi-note player working in simulation.

2. Setup Quartus Project

Click Quartus (Quartus Prime 18.1) on the desktop to start Quartus. Important: Ensure that the Quartus Version is 18.1 and not 23.1. Then, click Run the Quartus Prime software. You might need to try starting Quartus twice. Setup a new Quartus project using the New Project Wizard:

  • Directory, Name, Top-Level Entity
    • You must enter the working directory as follows with your NetID!
    • Working directory: C:\Users\netid\lab3d
    • Name of this project: lab3d
    • Name of top-level design entity: lab3d
    • Click Next
  • Directory does not exist. Do you want to create it?
    • Click yes
  • Project Type
    • Choose Empty Project
    • Click Next
  • Add Files
    • Click User Libraries...
    • Click triple dots to the right of Project library name
    • Click on This PC, then navigate to your cloned repo by choosing Windows (C:) > Users > netid > groupXX where XX is your group number
    • Click Select Folder
    • Click Add
    • Click OK
    • Click triple dots to right of File name
    • Click on This PC, then navigate to your cloned repo by choosing Windows (C:) > Users > netid > groupXX > lab3 where XX is your group number
    • Shift-click on every Verilog hardware design file (do not include any files in the test or sim subdirectories)
    • Click Open
    • Click Next
  • Family, Device, and Board Settings
    • Click Board tab
    • Family: Cyclone V
    • Select DE0-CV Development Board
    • Make sure Create top-level design file is checked
    • Click Next
  • EDA Tool Settings
    • Click Next
  • Summary
    • Click Finish

As in Lab 2, you must use the following steps to ensure Quartus knows your design includes RTL modeling:

  • Choose Assignments > Settings from the menu
  • Select the category Compiler Settings > Verilog HDL Input
  • Under Verilog version click SystemVerilog
  • Click OK

3. Music Background

Our multi-note and music player FPGA prototypes will use a piezoelectric ("piezo") buzzer. A piezo buzzer is a two-terminal device where one terminal is connected to ground and the other side is connected to a digital signal.

If the digital signal is a square wave then the frequency of the square wave will cause the piezo buzzer to play a note at that frequency. Essentially the piezo buzzer is a tiny speaker that can play notes.

Here is a table showing all of the notes and their corresponding frequencies and periods on a standard keyboard:

Here are the notes we will be using with our music player.

     freq    period
note (Hz)    (ms)
G3   196.00  5.102
A3   220.00  4.545
B3   246.94  4.050
C4   261.63  3.822
D4   293.67  3.405
E4   329.63  3.034
F4   349.23  2.863

We will need to use counters to create notes (i.e., square waves) with the appropriate period. Unlike the counter FPGA prototype which used a push button as a manual clock signal, here we will be using a real 50MHz clock on the FPGA board. This clock is named CLOCK_50 in the DE0_CV_golden_top.v Verilog file. A 50MHz clock has a 20ns period, but we want to create square waves with periods on the order of milliseconds. So we will use a clock divider to slow down the 50MHz clock by a factor of 1024 resulting in an effective clock frequency of 20,480ns (i.e., 0.02048ms). If we want a counter that is operating at a 0.02048ms clock period to wait for roughly 1ms it would need to count (1/0.02048) = 48.828 clock cycles. So if we want a counter to wait for roughly 1 second it would need to count 1000*48.828 = 48,828 clock cycles.

Recall that the note_period input to our note players actually corresponds to half the note period. If we set the note_period input to 100, it will actually produce a period of 202 cycles (i.e., we set the note high, count to 100, set the note low, count to 100). The extra two cycles are because of the extra LOAD_HIGH and LOAD_LOW states in our note player FSM. We need to take all of this into account if we want our note-player and music player FPGA prototypes to play the right notes.

                    num     note
     freq    period slow    period
note (Hz)    (ms)   cycles  input
G3   196.00  5.102  249.12  123
A3   220.00  4.545  221.92  109
B3   246.94  4.050  197.75   97
C4   261.63  3.822  186.62   91
D4   293.67  3.405  166.25   81
E4   329.63  3.034  148.14   72
F4   349.23  2.863  139.79   68

The num slow cycles is just the period times 48.828. The note period input is the number of slow cycles divided by two minus two.

4. Multi-Note FPGA Prototype

We will start by building a multi-note player FPGA prototype and use it to experiment with playing notes and visualizing the notes on an oscilloscope.

4.1. Integrate

We want to implement a multi-note player FPGA prototype with the following specification:

  • input to clock divider should be connected to the 50MHz clock on the FPGA board
  • rst should be connected to the reset button on the board (ACTIVE LOW!)
  • play_duration is set to 16'd8192 (resulting in short 167ms duration notes)
  • note1_period, note2_period, etc are set based on the background section above
  • The right three switches are for play_note_num
  • The first push button is for play_note_val (ACTIVE LOW!)
  • The first LED is for play_note_rdy
  • The two seven-segment displays in the middle are for play_note_num
  • The two seven-segment displays on the right are for note_sel (currently playing note)
  • The general-purpose pins will be used to connect the note output to the the piezo buzzer on the breadboard

Here is a template you can use for your top-level design.

//----------------------------------------------------------------------
// Instantiate the clock divider
//----------------------------------------------------------------------

logic clk;

ClockDiv_RTL clock_div
(
  .clk_in     (/* fill this in */),
  .divide_sel (9),
  .clk_out    (clk)
);

//----------------------------------------------------------------------
// Instantiate the multi-note player
//----------------------------------------------------------------------
// You need to connect the ports to the appropriate top-level ports.

logic [2:0] play_note_num;
assign play_note_num = /* fill this in */;

logic [2:0] note_sel;

MultiNotePlayer_RTL player
(
  .clk           (clk),
  .rst           (/* fill this in */),

  .note_duration (/* fill this in */),
  .note1_period  (/* fill this in */),
  .note2_period  (/* fill this in */),
  .note3_period  (/* fill this in */),
  .note4_period  (/* fill this in */),
  .note5_period  (/* fill this in */),
  .note6_period  (/* fill this in */),
  .note7_period  (/* fill this in */),

  .play_note_val (/* fill this in */),
  .play_note_rdy (/* fill this in */),
  .play_note_num (play_note_num),

  .note_sel      (note_sel),
  .note          (/* fill this in */)
);

//----------------------------------------------------------------------
// Seven segment displays
//----------------------------------------------------------------------
// You need to connect the outputs of the displays to the appropriate
// top-level ports.

DisplayOpt_GL display0
(
  .in       (play_note_num),
  .seg_tens (/* fill this in */),
  .seg_ones (/* fill this in */)
);

DisplayOpt_GL display1
(
  .in       (note_sel),
  .seg_tens (/* fill this in */),
  .seg_ones (/* fill this in */)
);

Use the following steps when you are ready to integrate the counter.

  • Double-click on DE0_CV_golden_top
  • Instantiate the template shown above
  • Fill in the connections to the top-level ports
  • Be sure to use `include "lab1/DisplayOpt_GL.v" at the top
  • Choose File > Save from the menu

Then make sure to hook up the piezo buzzer on the breadboard as shown. Consult the handout from Lab 2, Part C for more about using the breadboard.

4.2. Synthesize

We need to create a timing constraint file using the following steps:

  • Choose File > New from the menu
  • Click Synopsys Design Constraints File
  • Click OK
  • Enter the constraints shown below
  • Click File > Save from the menu
  • Name the file timing.sdc
  • Save the file in the lab3d directory

We will use the following constraints:

# Constrain paths that start at an input port and end at an output port
set_max_delay -from [all_inputs] -to [all_outputs] 20
set_min_delay -from [all_inputs] -to [all_outputs] 0

# Constrain paths that start at a flip-flop and end at a flip-flop
create_clock -period 20 [get_ports {CLOCK_50}]
create_clock -name clk -period 20 [get_nets {clock_div|counter_reg|q[0]}]

# Constrain paths that start at an input port and end at a flip-flop
set_input_delay  -add_delay -clock clk -max 0 [all_inputs]
set_input_delay  -add_delay -clock clk -min 0 [all_inputs]

# Constrain paths that start at a flip-flop and end at an output port
set_output_delay -add_delay -clock clk -max 0 [all_outputs]
set_output_delay -add_delay -clock clk -min 0 [all_outputs]

The only difference from Part C is we must specify the clock constraints in two steps. First, we create specify that the top-level CLOCK_50 port has a clock period of 20ns. Then, we we must carefully constrain the output of the clock divider so the tools know that this is also a clock signal.

Now use the following steps to synthesize your design.

  • Choose Processing > Start Compilation from the menu
  • Wait 1-2 minutes for synthesis to complete

How do I fix "can't open Verilog Design File" errors?

This probably means you did not setup the user library correctly, so Quartus cannot find the files you are including using the include Verilog preprocessor directive. You can use the following steps to fix this:

  • Choose Assignments > Settings from the menu
  • Select the category Libraries
  • Click triple dots to the right of Project library name
  • Click on This PC, then navigate to your cloned repo by choosing Windows (C:) > Users > netid > groupXX where XX is your group number
  • Click Select Folder
  • Click Add
  • Click OK
  • Choose Processing > Start Compilation from the menu to see if this fixes the issue

How do I fix "Verilog HDL syntax" errors?

This might be because you did not configure Quartus to use SystemVerilog! You can use the following steps to ensure Quartus knows your design includes RTL modeling:

  • Choose Assignments > Settings from the menu
  • Select the category Compiler Settings > Verilog HDL Input
  • Under Verilog version click SystemVerilog
  • Click OK

4.3. Configure

Now we are finally ready to configure the FPGA for our multi-note player demo.

  • Choose Tools > Programmer from the menu
  • Click Hardware Setup
  • Currently selected hardware: USB-Blaster [USB-0]
  • Click Close
  • Click Start

Try playing all seven notes. Use the input switches to set the note number then press the push button to playe the note. Make sure that the notes sound like they are increasing from lower notes to higher notes as you increase the note number.

Once you are sure your multi-note player FPGA prototype is playing notes, we will confirm that the prototype is playing the right notes by using an oscilloscope. An oscilloscope is a kind of electronic test equipment that graphically displays analog signals (i.e., voltage) vs. time. The oscilloscope has a "probe" which looks like this with a primary point, a ground probe point, and a 10x switch. Make sure the 10x switch is set to 10x not 1x!.

Connect the oscilloscope probe to your protoype as shown below. The green jumper wire connects from GPIO_1[1] from the FPGA to one side of the pizeo buzzer and the black jumper wire connects the other side of the piezo buzzer to ground. We have inserted two additional jumper wires on either side of the piezo buzzer to connect our prototype up to the oscilloscope. The yellow wire is connected to the primary probe point and the blue wire is connected to the ground probe point. You can obviosuly use any color jumper wires you like.

We will only be using a limited subset of the oscilloscope features. The buttons we will be using are highlighted below.

The following video by Prof. Batten provides a walk-through of how we will use the oscilloscope in this class:

Turn on the oscilloscope using the power button on top of the scope. You can always reset the oscilloscope to its default configuration by pressing the "Default Setup" button so do that now. After pressing "Default Setup" you need to press the "Menu On/Off" button to get the pop-up on the right side of the screen to go away.

The scope shows voltage on the Y-axis and time on the X-axis. The default configuration has 1V per grid line on the Y-axis and 4us per grid line on the X-axis. Now try playing a note by pressing the play_note_val button. You should see a signal briefly appear on the scope. We need to zoom out for a longer time window to better see the signal from our prototype. Rotate the Horizontal Scale knob counter clockwise to change the time scale to 1ms per grid line on the X-axis. The screenshot below shows you where the time scale is displayed.

We also need to adjust the Trigger which is used to tell the oscilloscope when it should capture a waveform. Rotate the Trigger Level knob clockwise a bit so that the trigger is about 1V higher than the baseline voltage level.

Now play the note again and you should be able to see a few periods of the note square wave. You can center the waveform vertically by adjusting the Vertical Position knob.

Now let's use the scope's measure feature to automatically measure the frequency and period of the note square wave. Press the Measure button. Use the Multipurpose knob to highlight Frequency. Then press the Multipurpose know and a little yellow square should appear next to Frequency indicating it is selected. Do the same thing to select Period. The following screen shot shows both Frequency and Period selected.

Then press the Menu On/Off Button twice to get the menu to go away. Now play a note again. In the lower left-hand corner of the screen the oscilloscope will tell you the measured frequency and period of the note square. Try all seven notes and confirm they match the expected note frequency and period as discussed in the above background section.

Now we will capture a screenshot of the waveform. Press the Single button and the play a note. The oscilloscope will capture the begining of the note square wave. To see more of the square wave, rotate the Horizontal Position knob counter clockwise. Then press the Single button and play a note again. You might see the first phase of the note square truncated. This is to be expected, because the note players are constantly playing a note and we are just caputuring when the multi-note player mux switches to the desired note. However, this does mean that the frequency and period measurements at the bottom of the screen are invalid when analyzing a single captured waveform.

We can use cursors to accurately measure the note square wave period after capturing a single waveform as follows:

  • Press the Cursor button
  • Rotate the Multipurpose button until the left cursor is roughly aligned with a rising edge of the note
  • Press the Multipurpose button
  • Rotate the Multipurpose button until the right cursor is roughly aligned with the next rising edge of the note
  • The oscilloscope will display the time between these cursors
  • Press the Menu On/Off button to hide the cursor menu
  • Confirm that this time matches the expected note square wave period

To save a screen capture, insert the USB flash drive into the port on the front of the oscilloscope. Wait a few seconds. Then press the Save button. Wait a few seconds. Remove the USB flash drive, insert it into your laptop, and confirm that you have captured the waveform. Once you have copied the screenshot to your laptop please delete it from the USB flash drive!

Note that if you press the Run/Stop button to make it green you can go back to viewing the "live" signal.

Now we want to make sure the multi-note player interactive simulator is working on ecelinux.

% cd ${HOME}/ece2300/groupXX/build
% make multi-note-player-sim
% ./multi-note-player-sim +switches=000

Pick a note (not note 000 which is a rest!) that you want to use for your check-off task and lab report. Play this note first using the interactive simulator which will generate a VCD file. Use Surfer to view the clk, note_sel, and note. Measure the period for the simulated note using Surfer. You can revisit the Part C handout for more on how to measure the note period using Surfer. Then measure the period for the real multi-note player FPGA prototype using the oscilloscope.

Lab Report Task 1: Save Screenshots for Multi-Note Player

Save a screenshot that clearly shows the period for your selected note both in simulation (using Surfer) and on the real multi-note player FPGA prototype (using the oscilloscope). You only need to do this for a single selected note!

Lab Check-Off Task 3: Demonstrate the Multi-Note Player

The TA will ask you to play all seven notes on your FPGA prototype. For each note, we want to hear note on the piezo buzzer and also see the waveforms on the oscilloscope. The TA will also ask to see your screenshots which clearly shows the period for your selected note both in simulation (using Surfer) and on the real multi-note player FPGA prototype (using the oscilloscope).

5. Music Player FPGA Prototype

We will now build the final music player prototype!

5.1. Integrate

We want to implement a music player FPGA prototype with the following specification:

  • input to clock divider should be connected to the 50MHz clock on the FPGA board
  • rst should be connected to the reset button on the board (ACTIVE LOW!)
  • play_duration is set to 16'd8192 (resulting in short 167ms duration notes)
  • note1_period, note2_period, etc are set based on the background section above
  • The right five switches are for play_song_num
  • The first push button is for play_song_val (ACTIVE LOW!)
  • The first LED is for play_song_rdy
  • The two seven-segment displays in the middle are for play_song_num
  • The two seven-segment displays on the right are for note_sel (currently playing note)
  • The general-purpose pins will be used to connect the note output to the the piezo buzzer on the breadboard

Here is a template you can use for your top-level design.

//----------------------------------------------------------------------
// Instantiate the clock divider
//----------------------------------------------------------------------

logic clk;

ClockDiv_RTL clock_div
(
  .clk_in     (/* fill this in */),
  .divide_sel (9),
  .clk_out    (clk)
);

//----------------------------------------------------------------------
// Instantiate the music memory
//----------------------------------------------------------------------

logic        mem_val;
logic [15:0] mem_addr;
logic [31:0] mem_rdata;

MusicMem_RTL mem
(
  .mem_val   (mem_val),
  .mem_addr  (mem_addr),
  .mem_rdata (mem_rdata)
);

//----------------------------------------------------------------------
// Instantiate the multi-note player
//----------------------------------------------------------------------
// You need to connect the ports to the appropriate top-level ports.

logic [4:0] play_song_num;
assign play_song_num = /* fill this in */;

logic [2:0] note_sel;
logic [1:0] state;

MusicPlayer_RTL player
(
  .clk           (clk),
  .rst           (/* fill this in */),

  .note_duration (/* fill this in */),
  .note1_period  (/* fill this in */),
  .note2_period  (/* fill this in */),
  .note3_period  (/* fill this in */),
  .note4_period  (/* fill this in */),
  .note5_period  (/* fill this in */),
  .note6_period  (/* fill this in */),
  .note7_period  (/* fill this in */),

  .play_song_val (/* fill this in */),
  .play_song_rdy (/* fill this in */),
  .play_song_num (play_song_num),

  .mem_val       (mem_val),
  .mem_addr      (mem_addr),
  .mem_rdata     (mem_rdata),

  .note_sel      (note_sel),
  .note          (/* fill this in */),

  .state         (state)
);

//----------------------------------------------------------------------
// Seven segment displays
//----------------------------------------------------------------------
// You need to connect the outputs of the displays to the appropriate
// top-level ports.

DisplayOpt_GL display0
(
  .in       (play_song_num),
  .seg_tens (/* fill this in */),
  .seg_ones (/* fill this in */)
);

DisplayOpt_GL display1
(
  .in       ({2'b0,note_sel}),
  .seg_tens (/* fill this in */),
  .seg_ones (/* fill this in */)
);

Use the following steps when you are ready to integrate the counter.

  • Double-click on DE0_CV_golden_top
  • Instantiate the template shown above
  • Fill in the connections to the top-level ports
  • Be sure to use `include "lab1/DisplayOpt_GL.v" at the top
  • Choose File > Save from the menu

The piezo buzzer should be hooked up the same as with the multi-note player FPGA prototype.

5.2. Synthesize

You should be able to use the same timing constraints as for the multi-note player FPGA prototype. Use the following steps to synthesize your design.

  • Choose Processing > Start Compilation from the menu
  • Wait 1-2 minutes for synthesis to complete

Now let's see how many gates our design is using.

  • Choose Processing -> Compilation Report from the menu
  • Under Table of Contents choose Fitter > Resource Section > Resource Usage Summary
  • Look through the report to determine the number of combinational ALUTs (configurable look-up tables) that are used for your design
  • Look through the report to determine the number of dedicated logic registers that are used for your design
  • Look through the report to determine what percentage of the total FPGA resources are being used (use the "Logic Utilization" row at the top of the area report)

Let's also look at the area on the FPGA used by the music player FPGA prototype using the chip planner.

  • Chip Planner
    • Choose Tools > Chip Planner from the menu
    • Identify where the logic used to implement your design is located in the FPGA
    • Choose File > Close from the menu to close the chip planner

Lab Report Task 2: Save Chip Planner Screenshot for Music Player

Save a screenshot of the chip planner. Clearly annotate on the chip planner the location of the music player FPGA prototype on the FPGA.

Lab Check-Off Task 4: Discuss the Music Player

A TA will ask you to discuss the number of ALUTs and registers. Look through your past reports to compare this to the number of ALUTs in the final five-digit display FPGA prototype from Lab 1 and the final two-function calculator FPGA prototype from Lab 2. The TA will ask you what percentage of the total FPGA resources are being used by the music player FPGA prototype. Show the TA your screenshot of the chip planner with the location of the music player FPGA prototype clearly annotated.

5.3. Configure

Now we are finally ready to configure the FPGA for our music player demo.

  • Choose Tools > Programmer from the menu
  • Click Hardware Setup
  • Currently selected hardware: USB-Blaster [USB-0]
  • Click Close
  • Click Start

Use the input switches to choose the song number. Try playing song 0 and song 1. You need to figure out the names of both songs.

Once you are sure your music player FPGA prototype is playing ongs, we want to also see these songs on the oscilloscope. The oscilloscope should be connected in the same was as for the multi-note FPGA prototype. Use the same process as for the multi-note FPGA prototype to view both songs on the scope.

Note that if you press the Run/Stop button to make it green you can go back to viewing the "live" signal. You will need to adjust the time per Y-axis to zoom out even further to see many notes. Rotate the Horizontal Scale knob counter clockwise to change the time scale to 400ms per grid line on the X-axis. View both songs and then pick either song 0 or song 1 that you want to use for your check-off task and lab report. Take a screenshot of the first few notes of the song using the oscilloscope.

Now we want to make sure the music player interactive simulator is working on ecelinux.

% cd ${HOME}/ece2300/groupXX/build
% make music-player-sim
% ./music-player-sim +switches=000

Play the same song you chose to look at using the oscilloscope, but now use the interactive simulator which will generate a VCD file. Use Surfer to view the clk, note_sel, and note. Make sure the note numbers (as indicated with note_sel match what you expect to see if you look in MusicMem_RTL.v. Zoom in out to see all the notes; can you see the long notes? Zoom in to see the note frequencies; can you tell the difference between the high and low notes?

Lab Report Task 3: Save Waveform Screenshots for Music Player

Save a screenshot that clearly shows some number of notes (does not need to be the entire song) for your selected song both in simulation (using Surfer) and on the real music player FPGA prototype (using the oscilloscope).

Lab Check-Off Task 5: Demonstrate the Music Player

The TA will ask you to play both songs on your FPGA prototype. For each song, we want to hear song on the piezo buzzer and also see the waveforms on the oscilloscope. The TA will ask you the names of both songs. The TA will also ask to see your screenshots which clearly shows the notes for your selected song both in simulation (using Surfer) and on the real music player FPGA prototype (using the oscilloscope). The TA will then ask you to play the secret song. You must figure out the name of the secret song. You can search online, ask other students, or even record the song on your phone and go outside the lab to find someone that knows the name of the secret song. The TAs will not tell you the name. You have to figure it out!

Lab Check-Off Task 6: Turn in Lab Kit

When you are finished with your demo, pack up your ECE 2300 Lab Kit. Put the piezo buzzer and wires back in the component box. Return the FPGA board, USB cable, and component box to a TA who will then record the kit number on your check-off sheet, initial the final check-off, and then collect your check-off sheet.

6. Optional Add-On: Custom Song

This section is an optional add-on to the main lab and is meant for students who have already completed all of the above tasks. Students can play a song of their creation on their music player by modifying the provided music memory in MusicMem_RTL.v. Open this file and you will see a large case statement that looks like this:

  always_comb begin
    case( memreq_addr )

      //----------------------------------------------------------------
      // Song 0
      //----------------------------------------------------------------

      16'h0000: memresp_data = NOTE_B;
      16'h0004: memresp_data = REST;
      16'h0008: memresp_data = NOTE_A;
      16'h000C: memresp_data = REST;
      16'h0010: memresp_data = NOTE_G;
      16'h0014: memresp_data = REST;
      16'h0018: memresp_data = NOTE_A;
      16'h001C: memresp_data = REST;

      ...

      16'h00FC: memresp_data = SONG_END;

      //----------------------------------------------------------------
      // Song 1
      //----------------------------------------------------------------

      16'h0200: memresp_data = NOTE_B;
      16'h0204: memresp_data = REST;

      ...

    endcase
    if ( !memreq_val )
        memresp_data = 32'b0;
  end

The case statement implements a large read-only memory. The notes are defined as NOTE_G up to NOTE_F, with REST signifying to play no sound. When MusicMem_RTL gets a request, it checks the address given by memreq_addr, and sets memresp_data to be the corresponding note. You'll see that the memory range for each song ends with SONG_END, to signify to our player that the song is finished.

As part of this memory, we've left a range (corresponding to song 2) for you as the student to implement a song of your choice, if you'd like. In MusicMem_RTL, you can find the following section:

      //----------------------------------------------------------------
      // Song 2
      //----------------------------------------------------------------
      // OPTIONAL: Replace note values to make a new song!

      16'h0400: memresp_data = SONG_END;
      16'h0404: memresp_data = SONG_END;
      16'h0408: memresp_data = SONG_END;
      16'h040C: memresp_data = SONG_END;
      16'h0410: memresp_data = SONG_END;
      16'h0414: memresp_data = SONG_END;
      16'h0418: memresp_data = SONG_END;
      16'h041C: memresp_data = SONG_END;

      ...

You can see that each note in the song is currently SONG_END. To write a custom song, you should replace as many of these values as needed with the notes for your song. Keep in mind that notes will lead directly into each other; if you want a break between notes, you will have to include a REST between them

Once you've created your custom song, you can re-synthesize your overall design (including MusicMem_RTL.v) and put your design on the FPGA, as described in earlier in this handout. From there, use the switches to select song 2. You should hopefully be able to hear your song being played by your music player!