We spent the week as a team working on perfecting our individual subsystems and working on perfecting the system interface and integration. Moreover, we conducted some user testing with mechanical engineers in TechSpark, as further detailed below. Everything is very much in progress, and we are well on track to be done with our project on Wednesday and have everything set up for demo day. Our schedule did not change, and there are no significant risks to project progress now that our user interface has been completed and is easy to use.
These are the set of tests we conducted for subsystems and the overall system:
Latency:
There were two main types of latency tests conducted, which were MIDI End-to-end latency tests and overall system latency tests. As mentioned in our final presentation, the following involved using an oscilloscope and cursor measurements to get the difference in time between the first MIDI bit being sent and the last signal value being sent out to the audio CODEC (and the GPIO pin connected to the FPGA for MIDI end-to-end latency tests).

We tried out all three types of MIDI commands supported in our system (noteOn, noteOff, controlChange) and averaged the latency out through multiple attempts (10 for each command type). This would be in conjunction with different types of signals and effects applied on them. We got the following values for such.
MIDI End-to-end latency: 1.324 ms
Overall System latency: 2.384 ms
This was all within our required <5 ms latency requirement, so no aspect of the system needed to be refactored.
Audio Accuracy:
While we use “audio accuracy” as the broad term for this, we really mean how accurate notes are with regard to cents. We recorded audio for all the supported notes in the Monoprice keyboard (with all four types of signals), and used a spectrum analyzer to extract the frequency value for the specific notes. We then averaged out the difference in cents to the expected value, and got the following:
Average Frequency Difference (in cents): 0.33 cents
Highest Difference in Frequency (in cents): 1.42 cents
This was all within the difference we were trying to be under, which was 5 cents, so no aspect of the system was changed.
Audio Quality:
For audio quality, we tested our different signals for the following metrics:
Total Harmonic Distortion (THD)
Signal to Quantization Noise Ratio (SQNR)
Spurious Free Dynamic Range (SFDR)
We recorded the output for each signal on a SystemVerilog testbench, capturing such on a .txt file. Afterward, we used a Matlab script and corresponding builtin functions to extract the metrics for each signal.

It yielded the following:
Sine
THD: -55.29 dB
SQNR: +44.99 dB
SFDR: +59.32 dB
Square
THD: -6.31 dB
SQNR: +30.10 dB
SFDR: +9.54 dB
Sawtooth
THD: -1.90 dB
SQNR: +25.33 dB
SFDR: +6.02 dB
Triangle
THD: -18.33 dB
SQNR: +108.37 dB
SFDR: +19.08 dB
These results are mostly expected, as sawtooth waves have strong harmonics and square have odd harmonics. The other numbers, particularly for sine waves, are not necessarily ideal. While triangle waves indicate barely any quantization, the rest show some semblance of such. At the moment these were measured, we were using 1024 samples for our waves. We had assumed that these were of high enough resolution to avoid signal quality issues, but going with a higher sample number could possibly mitigate some of these issues. While our sound was “good enough” at that point, we decided to attempt increasing our resolution to 4096 samples on Sunday, with the results to be recalculated for our final report.
ADSR:
For ensuring ADSR was working properly, we implemented a SystemVerilog testbench to capture and compare different ADSR values and their subsequent effect on the output. Afterwards, we compared this output and inspected the result to determine whether the envelope shape matched what we expected. This, combined with on-device testing, helped show that ADSR was implemented correctly.
Polyphony:
To ensure polyphony was working properly, we designed a SystemVerilog testbench. Because we were effectively creating a round-robin arbiter, understanding the logic of the module was not too difficult. However, on the actual FPGA there were still issues with how the input was being processed. To determine the source of these bugs, we implemented live debugging tools (specifically using the seven segment display and Arduino LEDs).
VGA:
For testing VGA, we knew that once we had some kind of image on screen it would be easy to continue development (and would most likely require no further testing). Thus, we deemed it most time-efficient to examine different VGA implementations online and go straight to synthesis rather than simulation. This is because we believed that the setup time for a debugging setup outweighed the time it would take to just set it up on the actual monitor. There was a slight bug with outputting the VGA SYNC clock, but this was an issue that came after synthesis anyway.
Effects:
To evaluate system behavior, we first implemented a SystemVerilog testbench to test specific components by inserting them into the wavetable/phase accumulator path and observing the resulting output. In parallel, we developed a fixed-point model in Python and compared it against a floating-point reference to quantify the error introduced by quantization. If this error fell within acceptable bounds, we then validated the fixed-point Python model against the SystemVerilog testbench results. To provide an example, during testing, both in simulation and on hardware, we observed that FM modulation introduced significant sideband activity, which ultimately led us to exclude it from the design.
UI:
For the user interface, we focused on minimizing setup time, targeting under five minutes for a first time user. To evaluate this, we recruited volunteers individually from TechSpark, provided them with a basic set of instructions, and timed how long it took them to complete the setup on their our computers. The results were encouraging: all participants finished in under five minutes, with the longest time recorded at approximately four minutes and thirty seconds, indicating that the system met our usability goal.
On average, we found that
Setup Time: 3 minutes and 16 seconds
We tested the measurements of the chassis (to make sure that it’s portable enough) with a tape measurer, and found
Chassis Measurement: 22.1 x 11.2 x 5.5 inches
Moreover, we weighed the overall system itself quite recently (chassis, FPGA, breakout board, Arduino) with a scale, and found
Chassis Weight: 6.72 lbs
Which was a little over our expected weight (5 lbs), but no changes were made to the system as it was within a reasonable bound due to the fact that we had not accounted for all of the interface additions (keys, LCD, plaque) in our initial weight metric. When we asked users, they said the system was portable enough to carry around, which also influenced our decision to make no changes to the chassis.
MIDI Interface:
To test the MIDI interface for correctness, I set up the FPGA’s hex display to show both the key note values and velocity values being transmitted to it. Moreover, the knobs were tested through the same manner, with the knob value and channel being displayed in the same location as the note values/velocity. I thoroughly tested for each of these, which verified that both the MIDIFsm and UART modules functioned properly. Apart from this physical testing, I had previously set up a SystemVerilog testbench to assert correctness with my UART modules, since adhering to timing rules was one of the most pivotal components of such.
Audio Interface/Communication Protocols:
Interfacing with the FPGA’s built in audio CODEC required the utilization of two communication protocols: I2S and I2C. For those two, I’d developed SystemVerilog testbenches to test correctness and accuracy with regard to timing, since it’d be hardest to debug in the physical board with an extremely fast clock. Things like checking for correct timing on the acknowledge bits and start/stop conditions were all covered. After this, testing if the audio interface worked went hand in hand with testing the different types of signals. I would connect audio output onto an oscilloscope and play different signals, checking if it visually matched whichever had been chosen. Apart from that, we’d check if the audio of the waves would correspond with what we had expected to hear.











