I'm Trevor Dawideit, a Computer Engineering Major with an expected specialization in wireless systems at Stevens Institute of Technology
5.1
I'm Michael DiGregorio, a Computer Engineering Major with an expected Graduate Certificate in Artificial Intelligence and a focus in financial modeling at Stevens Institute of Technology
I'm Angelo Cardinale, a Computer Engineering Major with an expected concentration in Power Engineering and a Minor in Electrical Engineering at Stevens Institute of Technology
I'm Chris Waldt, a Computer Engineering Major with an expected specialization in embedded systems at Stevens Institute of Technology and an absolute unit
The main objective of this project was to create an FPGA-based system able to take advantage of the expanded input and processing capabilities of an external board. In our case, we found the Arduino Uno to be a good choice for a proof of concept. It has a large number of digital I/O pins, an inbuilt ADC, and an intuitive programming interface. We also decided to showcase the expanded I/O by creating an audio synthesizer which uses buttons attached to the Arduino as piano keys.
The original vision of the team was a full electronic keyboard built off of the Nexys DDR4 board, which took keyboard input as a way of determining which notes to play. This implementation never left the prototype stage of the project. We had trouble with two integral components of this project. First, the sinetables were difficult to generate on the FPGA board, so we generated them with python and tried to load them in. Unfortunately, static memory is difficult to manage in VHDL. While not insurmountable, this issue was compounded by the lack of a keyboard input driver for our Arduino.
This was replaced with the version of the project that we ended up implementing. We used a set of buttons connected to an Arduino to send digital output signals to the PMOD Ports of the Nexys DDR4 board. From there, an appropriate waveform would be generated and the output through another PMOD Port, into a DAC, and then into a speaker.
The system was designed to be easily extendable, and it is possible to expand the number of notes through increasing the number of PMOD Ports and buttons.
The Arduino code used to test the circuit and validate proper digital outputs was relatively straightforward. It revolved around reading in digital inputs to the digital I/O pins and then printing which pins were high to the serial monitor. The digital I/O pins used were Pmod ports on the Nexys 4 DDR board. These ports have a multitude of uses being able to work with sensors, communication interfaces (such as WiFi and Bluetooth), and I/O ports. The Pmod pins on the Nexys 4 DDR board were a double 6 pin setup with pins 1-4 being for data transfer and 5-6 used for ground and power.
As for the hardware switches used for the board, the design was modular to allow for expansion, and made simple for ease of trouble shooting and the integration of additional components should it be desired. The Arduino's 3.3V rail was used as Vdd. The switches rest closed, allowing a path to ground for the signal wires. This sets the "resting output" of the system to be 0V. When the switch is depressed, the path to Vdd is opened and the signal is pulled up to 3.3V.
The PMOD I/O software was initially developed in isolation in order to speed up the overall development process. The construction of this software began with its constraint file. This is used by the NEXYS board to establish which hardware components will be referenced by the rest of the code. In this case, the team decided to use the first four pins of PMOD port JA (for additional information on PMOD ports, check out our contributions page). In the VHDL code the four pins were ported in as a STD_LOGIC_VECTOR of size 4 down to 1. This allowed us to represent the four pins as a single sequence of 1's and 0's.
In order to determine which pin is high, we would only need to check to see which bit in the binary sequence xxxx is a 1. For example, if the sequence is 0110, the second and third inputs are reading HIGH while the first and fourth are reading LOW. Once this is known, this software hands over control to the sound wave generation program, where a predetermined note is generated and output through the DAC.
The sound generation engine is based off of the DAC siren project from Lab 5 with most alterations being made to the tone and wail code to enable the board to generate and output different wave-forms at specified pitches.
The tone code specifically handles the task of generating the specific wave-forms. Each wave is generated by modulating the amplitude of the voltage being outputted from the DAC attached to the board at a set frequency. Each wave is split into 4 quadrants which simplifies creating each part of the wave. A 14 bit signed integer named index is modulated in each of the 4 quadrants according to the shape of the waves. For the Square and 50% pulse wave, the index value is simply set to high and low values where as it is changed according to a linear function in both the triangle and folded saw waves. The difference between the square and 50% pulse wave is that the index value is set to the high value for half of the wave cycle for the former and only 25% of the cycle for the latter. The triangle wave has functions with both positive and negative slope while the folded wave has repeating positive functions that give it it's buzzy characteristic. The waves are selected by reading in the binary pin values from the PMOD code.
Pitch is handled by wail code and is controlled by a 14 bit unsigned value that sets the pitch in increments of .745Hz. Initially we set out to program in an entire song, however that would have required a separate clock divider and sequence code that would have greatly complicated the project. Instead specific note values are set using the same input binary from the PMOD used in the tone generation.
Below are screenshots of the oscilloscope readings, phase and frequency response of each wave.
Demo: