Exercises_WaveformGenerator

=Introduction= The AMVE must be able to generate a digital sinusoid waveform. The waveform generator will be used as a tone generator for later signal processing- and interfacing exercises. The waveform generator contains two registers accessible by means of the Avalon-MM bus, these registers allow manipulation of the sinusoid frequency and amplitude. The waveform is created using a look-up table in a ROM memory block with predefined values. To speed up the design process, a template design is provided. The files provided should be copied into the existing amve folder (after a backup of the existing files). =Goal=
 * Create a waveform generator to generate tones for later signal processing and audio interfacing exercises.
 * Get experience with PLLs, clocks and clock domains
 * Get even more experience with test benches and simulation

=Design= The design is build around a ROM containing a normalized sinusoid. The values are 24-bit, 2’s complement, which is commonly used for digital audio.

The output signal is generated by looping thru the ROM. The pace used, sets the output frequency. The address counter is fed by the system clock and a clock enable signal generated by a clock divider. The system clock is first divided by a fixed amount (prescaler) of four, and then by the value given in the WF.FREQ register: Fwaveform = Faddress / Nsamples = Fsystem / (Nsamples * Prescaler * WF.FREQ) Example: Fwaveform = 12 MHz / (180 * 4 * 16 samples) = 1041 Hz The ROM initialization file provided contains a sinusoid with 180 samples (Nsamples = 180). A good choice for the pre-scaler is 4.

Step 1: Create the basic Waveform Generator

 * 1) Use the WaveforGenerator design-entity provided. Create the two processes shown in the figure above:
 * One process creates the CounterEnable signal, by dividing the 12MHz clock. The divider is the sum of the pre-scaler value and WF_FREQ register (but use a constant for now!).
 * The second process must contain a circular counter that increments, when CountEnable is high. The count value is to be used for selecting the ROM address input.
 * The processes must use the 12MHz clock signal as this is the clock source for the audio sub-system. If you need a reset signal for theprocesses, you must consider the how to let the csi_clockreset_reset_n signal pass to the 12MHz clock domain.
 * 1) Use the supplied testbench to simulate that the counter works.
 * 2) Create a “ROM: 1-PORT” component using the MegaWizard. It must be 24 bits wide and contain 256 words. Don’t use an output register (q), and specify a memory content file : “SinusiodROM.hex”. See the guidelines in the Wiki.
 * 3) Add the ROM to the project and instantiate it in the WaveforGenerator entity. Connect the ROM address to the counter output.
 * 4) Simulate! In the waveform window change the “radix” to “decimal” and “format” to “analog” for the ROM output signal. You should be able to see a sinusoidial waveform!

Step 2: Use registers to regulate frequency and attenuation
Create the functionality of the two registers: Waveform Frequency Register and Waveform Annutation Register. See the wiki page for the required functionality. The interface to the Avalon-MM bus and the storage of the the values is already implemented in the template file.
 * 1) Use the value of the WF_FREQ register to set the value in the clock divider.
 * 2) Use the WA_ATT value to attenuate the AudioData signal. Hint! Use “shift_right” and “signed” (signed because the waveform is 2’s complement).
 * 3) Run simulation again and verify that the default values are used.

Step 3: Compile it in Quartus

 * 1) In Quartus, create a new clock in Assignments->Settings->Classic Timing Analyzer..-> Individual Clocks. Create a new clock setting. Pick “Clk” pin in the node finder, and set the required Fmax = 50MHz.
 * 2) Run Compilation, and view the timing report afterwards. You will probably get timing errors on the signals crossing the clock domain in the WaveformGenerator, namely WF_FREQ and WF_FREQ_avs and the same for WA_ATT.



To tell the analyzer that we allow the signals to take multiple clock cycles to settle, we have to specify the “multicycle” assignment for the two registers in the assignment editor. Set the value to “2”. And pick the in- / outputs in the node finder.




 * 1) Re-run compilation, this time it should be successful
 * 2) You will not be able to test the design on your board yet! (We need the codec to get it to work)