I spent a lot of this week doing experiments with FPGA usage and deciding the best way to design both the wavetable and the delay/reverb modules. In this status report, I will describe the experimentation done, the process this week of designing some of the effects modules, and some miscellaneous items as well.
Wavetable Experiments
I started out the week working on wavetable size experiments, something I wanted to get done as early as possible (as mentioned in last week’s report). Since we wanted to avoid putting the wavetables on a memory external to the actual FPGA chip, such as SDRAM or flash, I wanted to see what the FPGA usage would be if I just put all the wavetables in the FPGA LUTs themselves and create a big combinational lookup table to act as the wavetables. Jens generated a 12-bit, 512 sample sine wave to test this idea with, and the results were a lot better than I thought! It turns out, a single one of these tables uses about 3% of the available LUTs on the smallest Terasic DE0 board (Cyclone III) used by the old iterations of 18-341. I tested with additional tables present, and the number of LUTs used scales linearly. In general, it seemed that the usage was approximately 1 LUT per 12-bit sample. However, I was recommended by Prof. Mai and Ford Seidel to explore using the FPGA’s block ram for wavetable storage instead and it seems like this will be a good solution as well. One big advantage of using the block ram is that the Quartus generated block ram modules are two ported, which will make Jens’s life a lot easier down the line when he makes the wavetable access modules. However, one downside that worries me is that using the block ram will make our design board dependent, since different boards will all have different amounts and types of block ram. While this isn’t a major problem, I had wished the design could be as portable as possible. We don’t anticipate needing to do a radical board change and any board changes will be all in the same Altera Cyclone family.
Reverb and Delay Design
I also started designing the reverb and delay modules this week. The two effects are very closely related at first glance, but are actually quite different in the nitty-gritty. Both involve creating a delay queue where the samples will pop out some number of cycles after the sample is played normally, however the queue for the reverb module will feed back into itself after being attenuated to create an echoey effect and will also be shorter than the queue for delay. Unfortunately, since the sample rate for standard audio is 44.1kHz, we will need to queue up 44,100 16-bit samples in order to create a one second delay. As with the wavetable experiments, I tried to create a quick prototype module in Quartus to see the FPGA usage of a naive implementation of the queue, but it ended up being completely crazy and infeasible (also learning that Quartus will only allow a generate loop to go 5000 iterations before dying). A 16-bit sample queue with a queue depth of only 4096 elements alone will take up 65k logic elements on a board, almost 5 times the amount on the Terasic DE0, and this queue is only big enough for less than a 100ms delay! I was again worried that I would have to deal with the on-board SDRAM and would need to hack up a controller, but luckily, it seems like block ram will come to the rescue again. The Quartus Megafunction wizard will let you synthesize a FIFO structure on block ram, which was awesome to find out, but unfortunately, a 16-bit FIFO of length 216, a queue depth that would allow for a maximum delay of a bit less than one second, would take up 64 M9k block rams, whereas the DE0 board only has 56 such block rams. I don’t see an alternative path to implementing delay with any reasonable maximum delay, so this will probably force us to switch from the DE0. Luckily, we already had plans in place to switch to the Terasic DE0-CV, an updated board that is almost identical except for using the Cyclone V FPGA instead of a Cyclone III. The new FPGA has 308 M10k block rams, about 6 times the amount as the old board, while only being a little more expensive as to not increase the total project cost by too much. This has the added benefit of allowing us more block rams to add more wave shapes later on, something that will not take a lot of time or be too difficult, while make the user experience of the synth significantly cooler. In addition to nailing the exact implementation of the queues for the delay and reverb effects, I also got around to designing the other parts of the effect.
Miscellaneous
Finally some other miscellaneous updates. I put in the purchase order for the MIDI keyboard on Monday after lots of agonizing over it being the first purchase of the project and received the keyboard on Thursday. Unfortunately I don’t really have a good place to put it yet so it’s being hidden in the capstone lab. I plan on running some tests with the keyboard, and try interfacing it with the FPGA early next week. A lot of time this week was spent working on the presentation and documentation rather than on implementation, but I’m not too worried since a lot of the planning for future steps was hashed out this week as well. Running the tests helped lock in a lot of important design considerations for the modules that needed to be done, so overall things are running pretty smoothly.
Goals for Next Week
For next week, I aim to finish the complete design of the reverb and delay modules, and hopefully have a Verilog description mostly or completely written. I want to start testing the MIDI interface between the keyboard and the board as well. Since the comprehensive design review report needs to be done next week as well, I will not expect all of these goals to be achieved but I expect them to all be well underway.