Audio Visualization

Final Project – ECE 5760

Michael Lyons – mpl56

Darbin Reyes – der34

 

 

Introduction

 

            The goal of our project was to input a signal in the DE2 board, whether it be music, conversation, or noise, and be able to analyze the signal to display visuals on the VGA output in real time. The main focus and testing for this project was done on music being played through a computer. The setup used for the project was a DE2 board, the on board audio codec, and VGA display driver with an external monitor. The setup would have the user input their music on the board line in and then the logic of our project would output visuals on the VGA port according to the signal coming in. Once the signal was input into the line in signal differentiation was needed and done by amplitude, frequency, and period. Using these different measures for the incoming signal the user selected from various visualization schemes to display. The amplitude of the incoming signal over time was converted to a logical mapping for the VGA and allowed for different size objects on the VGA display. Frequency and period being very closely related were dealt with in different ways. For frequency we used five filters in order to separate the incoming signal into three bands. The bands corresponded to bass, cymbal, and vocals and depending on amplitude and content in each band the display showed different patterns and colors accordingly. The final measurement, period, was used in a different way for the variation of the pixel colors on the VGA display. Depending how long the period was the color schemes would change according to that pace. The variation of pixel color was also done at faster paces, so if the beat detected occupied quarter notes pace the colors could change with a quarter note, half note, whole note, and two half notes. The exact timing of each note is not necessarily accurate; however, relative pacing or beats per minute (bpm) of the music was the goal. The reason this project was chosen was because audio visualizes are common to find but do not necessarily correspond to the music being played. The goal of this project was to create visuals that actually followed the music for a better listening experience.

 

High Level Design

 

            The critical path of this project was to take an input signal from the audio codec and then send this signal through various calculation and visualization modules to produce an output on the VGA display. The block flow diagram of the high level design can be seen below in Figure 1.A second more precise visualization unit was also created and is explained in the hardware section and used for obtaining accurate and simple results. The first unit that the audio input signal was sent to the period calculation unit in the top module. The period calculation unit repeatedly finds the period on the expiration of a timer and stored the largest period found in a register. The period calculation was done through the method of zero crossing. Before detecting zero crossing the audio signal had to be low passed and down sampled so that only low frequencies could be used to figure out the period. Using the low frequencies is beneficial because it gives a good estimate of the beat of the song. With the beat of the song one can change images and colors in a period manner with the music being played. In order to accomplish finding the period to estimate beats per minute a CIC filter was used to low pass and down sample to the audio clock. From there the signal was down sampled even more using a thousand hertz. According to the Shannon’s sampling theorem this would only allow frequencies of up to 500 Hz to be detected. A frequency from 500 Hz and down is the bass range of the music where the beats can usually be found. After the filtering and down sampling are completed three zero crossings are found so that an entire period is traversed and the resulting number of clock cycles is used to judge beats per minute which is then used to change the image as well as the color on the screen.

The audio signal is also sent into three low pass chebychev filters each with a different cutoff frequency for their respective ranges of: bass, cymbal, and voice. The filters used were all infinite impulse response filters. The cymbal filter used a four pole eighteen bit infinite impulse response filter which was for the highest frequency range. The bass and voice filters both used a four pole twenty seven bit infinite impulse response filter because the cutoffs needed to be very exact considering the ranges were tight on the lower end. Details about the filters can be found in the hardware description section below. The cymbal and voice filters required two filters to create a pass band while the bass filter was a single low pass filter

At the same time the audio input enters the three filters the signal also goes into an absolute value unit and then a height mapping unit. The absolute value unit takes the absolute value of the incoming signal and then sends it to the mapping unit where the height is converted to a height mapping of the VGA screen.  The absolute value unit takes the absolute value of the current input signal by checking the first bit and makes sure that it is zero. Once the signal has been made positive it goes into the height mapping module which looks for the highest order one and once found the unit outputs height that corresponds to a pixel quantity for the y axis on the VGA display. The resulting height allows visuals to be drawn with heights that are proportional to the incoming audio signal. The three audio filters mentioned in the paragraph above are also put through these two units to output their corresponding heights.

 

Figure 1: High Level Flow Diagram

 

            After the filtering, period calculation, and height mapping the audio signal is then sent into three different display modules selectable by the user.  The first of these modules is the “Cellular automaton module” which takes the period, the audio input, and the three filtered signals. The Cellular automaton unit draws a cellular automaton on the VGA display. A Cellular automaton is an algorithm where the next line on the VGA screen depends on the previous line on the VGA screen. How the next line on the screen is determined is based on the current line’s values. Beginning with an initial value, which in the case of our implementation could be either one block in the center or a horizontal line of random values, the next horizontal line will be set values based on the horizontal line that came before it. How the next horizontal line is set based on the previous line is done with a rule that is from zero to two hundred and fifty five or eight bits. Each rule can be represented by an eight bit number. Each bit in that eight bit sequence can be reached with a three bit number that represents its offset within the eight bits. For instance the fourth bit has the sequence 3’b100 associated with it. When given a rule in eight bits the offset sequence is contained in the previous line. When traversing a horizontal line the three bits or pixels in this case when referring to an LCD screen, the pixel above the current one is checked as are the pixels immediately to the left and right of the pixel right above. If any of these pixels is encoded as drawn then that bit is set high in the three bit offset. If the bit offset into the rule is a one then the current pixel on the screen is to be filled in. If the bit offset into the rule is a zero then the current pixel is to be black. In our implementation of the Cellular Automaton the rule is dictated by the high order bits of the period and the color of the current pixel is not black or white but based off either output from a pixel value controller or from the various audio signals contained within the project. The various rules calculated and colors generated produce an array that is stored in SRAM. The VGA then reads the values out of the SRAM if the Cellular Automaton visualization is selected by the user.

            The second of the visualization module is the “draw bars” module which takes in the period of the signal, the audio input, the three filter outputs, and the height bit mapping of the audio input signal, the bass filter, cymbal filter, and voice filter outputs. Once all of these calculated values are read into this module the current section of the screen VGA is trying to set is traversed and as it is the draw bars visualization figures out what to draw in the current location the VGA is looking for. In other words the VGA looks over the entire screen from the top left down to the bottom right. The module for the VGA outputs the current location that it is looking for and this is an input into the module. Based on this value the module finds out its current offset across the screen and the corresponding height bit mapping for that location on the screen and if the height mapping includes the current location then the pixel controller unit outputs a new pixel value to the VGA display. The draw bars visualization draws one hundred bars across the VGA display representing past values of the audio input signal. The current sample of the audio signal is stored in the first height map register and as more samples are loaded in, the sample in the first register is passed to the next bar height register. In this manner the height map value is passed down the bar height register chain and the height is propagated across the screen. In this manner the magnitude of various parts of the input audio signal can be seen over one hundred redraws of the screen at one time. In addition to the bars being drawn across the screen there are two “eyes” at the top of the screen that change in size with respect to some of the height registers of the bars to represent the frequency of change in the magnitude of the current signal being displayed by the bars. The colors in which both the bars and “eyes” are filled in with can be changed by the user. The user can choose to have the pixel controller run through its basic algorithm to change the pixel colors or the user may select the available audio signals to dictate the current color change. With this unit it is very clear to tell the magnitudes and how the waveform progresses over time but the period is a bit abstract since it is only used in the default algorithm to change the pixel color scheme. When this visualization and color scheme are selected by the user the unit will produce red, green, and blue pixel values which are output by the unit and onto the VGA display.

            The third of the visualization modules is the “box visual module” which takes in the current calculated period, the input audio signal, and the filtered bass, cymbal, and voice signals. The “box visual module” also takes in the coordinates being traversed by the VGA controller and tracks the current position on the screen and divides the screen up into four concentric rectangles instead of draws bars and eyes. The concentric rectangles are drawn using a grid fashion and depending on the rectangle in the grid the VGA controller is currently traversing it is filled in with pixel values from the pixel controller. Each rectangle on the grid not only can change its color using the pixel controller but it can change in size. The grid is divided up to the various audio input signals. The outer most edge’s blocks in the grid all have their widths modulated from the left and right by the audio input signal’s, from the line in, top four bits not including the sign bit. The inner most grid component in the center of the screen has its width and height, of both sides, modulated by the filter voice signal’s top four bits not including the sign bit. The second most inner rectangle has its width modulated from both sides by the top four bits of the cymbal input signal. The height on the other hand is not modulated in all section of this rectangle. Only in the bottom and top row of the second most inner rectangle is the height adjusted for the top four bits of the cymbal audio input. The second most outer rectangle works in a similar manner as the last rectangle but the width in both direction modulated by the top four bits of the bass input signal. Only the bottom and top rows of this rectangle are modulated in height by the top four bits of the bass input signal. The top four bits of the inputted signals do not include the sign bit so that magnitude is the measure seen when changing the grid block size.

            After all the visualization modules red, green, and blue pixel values are all set and read into the VGA controller appropriately to the visualization scheme selected by the user. The VGA controller then outputs the created display onto the LCD display in the lab. The pixel color values seen on the VGA display are drawn either from audio and filter inputs or from the pixel controller instantiated along with each visualization module. The goal of the pixel controller is to dictate how quickly the “pixel variater” steps through its various pixel encoding schemes. The “pixel variater” steps through the different combinations of colors over time based on the current scheme passed in by the pixel controller. The speed at which the schemes change is dictated by a counter that terminates by a multiple of the period. Finally, other than the filters and filter generated code, audio codec, and VGA modules given to us previous in the ECE5760 lab, there are no existing patents, copyrights, or trademarks associated with our project. There are also no standards used in our project.

 

Hardware

 

            Referring the high level design flow and starting from the input signal we can begin to traverse the hardware used for this project. The input signal goes into the audio codec which is then input into the FPGA chip on the DE2 board which allows the audio signal available for manipulation and analysis. The inputted audio signal in our design can be directly placed on the output line depending on the selection of switches 16 through 14. This is a three bit value that when that choose the output to be the output of the CIC filters, the audio signal input, the cymbal filter output, the bass filter output, the voice filter output, and the 1000 Hz sampling of the audio input signal for the numbers zero to five respectively. If none of these values are selected using the switches then nothing is output on the left channel of the line out. On the right channel the same content is placed as was placed on the left channel.

            The input from the audio codec is also used in a top module section of code known as the period calculator. The period calculator takes the audio input signal from the left channel and attempts to find the low frequency periodicity of the signal. The first step in completing this task is to filter the audio signal input through a second order CIC filter. CIC filters were used in lab two of ECE5760 and won’t be discussed in great detail here. The purpose of the second order CIC filter is to low pass the signal using the twenty seven megahertz clock and the audio clock. The second order CIC filter also down samples the signal to the audio clock and then outputs the corresponding signal on the ‘oCIC’ wire.  After the low major section of the period calculator code is entered, which is an always blocks in the top level module at the positive edge of the fifty megahertz clock. The first task for the period calculation is to down sample the second order CIC filter output even further. In this loop the count, hzCount, is used to create a 1000 Hz clock by switching the register value of clk1000 every 25000 clock cycles. This creates a 1000 Hz clock signal which will be used to, based on the Nyquist sample rate, to remove all frequencies above 500 Hz. With all the high frequencies removed the hardware can now calculate the period of this low frequency signal by looking for three zero crossings in a row. Three zero crossings in a row traverses one period because in one period a sinusoid will cross the time axis three times. The crossing of the time axis can occur in the sequence of below, above, below or above, below, above and the period is the number of cycles between the going below samples or the going above sample respectively.

Before looking into the state machine it is worth noting that when the system is reset the maxPerLength, prevSample, and newMax are all set to zero and state1000 is set to firstSample.  The maxPerLength is the maximum period length recently measured. The prevSample is the previous sample that was in the register sample1000 and newMax is a counter that dictates when a new value should be placed in maxPerLength. Other registers used are periodCount, periodLength, state1000, and modIn which are the period cycle count, current period length measured, the current state of the period calculator, and the down sampled audio signal from 50 MHz to 27 MHz. After the reset is no longer being pressed the state machine samples the sinusoid when the 1000 Hz clock is high and then goes to second state of fristCross which checks to see if between the pervious sample and the current sample if there was a change in sign. When there is a change in sign it shows that there is a crossing of the time axis because the magnitude goes from positive to negative. If there is no change then the current sample is stored in previous sample and the firstSample state is returned to. If a zero crossing is detected in either direction the periodCount is reset to zero. The periodCount is a 32 bit register which is used to measure how many clock cycles the period is. The current sample (sample1000) is stored in the prevSample register and the state1000 progresses to secondSample. In secondSample a similar action as in firstSample is taken where if the clk1000 signal is high then a new sample from the second order CIC filter is obtained and the secondCross state is entered. The secondCross also attempts to see if there is a zero crossing and returns to the secondSample state if there is no zero crossing. If there is a zero crossing then sample1000 is stored in prevSample and the state1000 is changed to thirdSample. In state thirdSample it also waits to obtain a new sample when the clk1000 is high and otherwise simply wait until the clk1000 is high. Once the clk1000 is high the thirdCross state is entered and if no zero crossing is detected then it returns to the thirdSample state. If a zero crossing is detected then the periodCount is stored in periodLength. The periodLength is compared to maxPerLength which stores the maximum period measured in this interval so far. Storing the maximum period allows us to obtain the lowest frequency possible which is useful for measuring the amount of time between the bass beats in the music. Then the newMax value is increment and checked to see if it has reached 1000 yet. If the newMax register has reached 1000 then maxPerLength is step to 1000 and newMax is set back to zero. The newMax count is implemented because most audio signals are dynamic and will have a constantly changing lowest frequency so it is useful to want to measure a new maxPerLength every so often to allow the visualization to keep pace with the current audio signal. The maxPerLength register is then put on the hex displays for the user to view.

 

Audio/Video Synchronization

 

A filtering scheme was developed to facilitate synchronization of the music to what is being drawn on the screen. While common audio visualizations do not stress synchronization, this scheme does. We found that for the user to easily notice the synchronization between the music and the screen, the drawing had to remain simple. As such, the visualization schemes for which the audio and video are visually in synch the drawing was kept simple. On the other hand, to add visually complex visualizations, we had to sacrifice synchronization with the audio. With the complex scenes, the synchronization is not immediately obvious, but the presented visualization is modulated by the audio to produce variation on the screen. The following explains the filtering scheme developed to produce audio visualizations for which the synch is obvious. The visualization schemes that focused intensely on simplicity of visuals and synchronization with the music are explained below under the simple visualization section.

 

Filtering Scheme

Figure 2: Filtering Hardware

 

The filtering scheme seen above was used in a separate hardware module for simple visualization and is separate from the main part of the hardware shown in the flow diagram in the high level design. The filtering scheme has five main components:

 

1)      A filter bank with 3 filters. Low pass, band-pass, High Pass.

2)      Volume adjustment module.

3)      Absolute value unit

4)      Thresholding

5)      Conversion to bar height

 

The filter bank contains three Chebychev, fourth order, infinite impulse response (IIR) filters. The verilog implementation of these filters was taken from the ECE5670 website here:

 

http://instruct1.cit.cornell.edu/Courses/ece576/DE2/fpgaDSP.html

 

The cut-off frequencies were chosen by testing the filters in Matlab on various songs.  The cheby1() function in Matlab was used to do this. The final normalized cutoff frequencies used were:

 

Chebychev Low Pass:  .03

Chebychev Band Pass:  .02-.05

Chebychev High Pass:  .5-.6

 

With the audio codec running at 16bit resolution and 48KHz.

During testing of the filter output, we observed that although the desired frequencies were filtered, each filter unequally attenuated the input. For example, even when the high pass filter input contained significant amounts of high frequency sounds (e.g. cymbal beats), these frequencies were barely audible relative to the other filter outputs.  This problem was easily solved by manually increasing the volume, however we found that it easy to develop a method for automatically adjusting the volume. The scheme for volume adjustment is simple. We take the average of the absolute value of the filter output and increase the volume if it is below a certain threshold. The amount of volume increase is proportional to how far the filter output is from the threshold. The absolute value unit then takes the absolute value of its input. This is a significant step toward visualizing the audio. It is easier to modulate visuals on the screen with a signal that is proportional to the absolute value of the audio amplitude.

   Using a threshold comparison on the absolute value of the audio signal is used to accomplish three tasks. First, it is used to prevent noise because even when there is no audio input, the audio line-in produces non-zero values due to noise.  This caused unwanted random modulation on the screen. This issue was solved by continuously averaging the absolute value of the input over a half second period which acts as a low pass filter. If this average is below a certain threshold, the input is considered zero. We also threshold the absolute value of the filter output to ensure that the modulation used for drawing is not too hectic. This makes it easier to identify drum beats in the signal. This can be easily illustrated in Matlab.  The following figures show the original input, the low pass filtered input, and the thresholded low pass filtered input. The peaks in the figure where a threshold is used correspond very closely to the drum beats in the music. The resulting signal can be used successfully to create audio visualizations which are in sync with the music. In general, this scheme allowed us to isolate drum beats from the low pass filter, voice and guitar from the band pass filter, and cymbal beats with the high pass filter.

 

Figure 3: Raw audio input.

Figure 4: Low pass filtered

Figure 5: Low Pass filtered with threshold

 

Lastly, to implement a bar visualization scheme, the filter with a threshold output was run through a look up table (LUT) to associate it with a bar height. The final place where the audio input signal is used besides the visualization module is in the height mapping process. The three filter range outputs are also put through the height mapping process as well. The first step for all four of the signals to be height mapped is to send them all through an absolute value unit. Each absolute value unit makes sure the highest order bit is zero or that each output from the absolute value unit is positive. These outputs are then fed into firstHbit height mapping module. This module finds the highest order bit that is a one and then sets the corresponding mapping to a pixel amount vertically on the screen. The mapping computed here is used to send data to the VGA controller that is coordinate specific and is described below in the simple visualization section.

 

Audio Codec

 

            The audio codec used for this project included five files which were AUDIO_DAC_ADC.v, I2C_AV_Config.v, I2C_Controller.v, Reset_Delay.v, and VGA_Audio_PLL.v. The use of this hardware was to be able to send and receive sixteen bit signals from the line out and line in ports on the DE2 board. The input audio signal is run into the DE2 board for calculation and then can be output again by the user on the speakers in lab so both listen and watch the music unfold in front of you.

 

VGA Controller

 

            The VGA controller used for this project included four files VGA_Controller.v, VGA_Param.h, Reset_Delay.v, and VGA_Audio_PLL.v. The reset delay and PLL files are duplicate files used between both the audio codec and the VGA controller. The VGA controller had a clock that was used to coordinate the cellular automaton drawing. Also the VGA controller’s current x and y coordinates were used to place pixels to of a certain color on the screen. If the coordinate values were in between particular ranges then a certain color scheme could be used to fill in the LCD display. The pixel values were read into the VGA controller using the mVGA_R, mVGA_G, and mVGA_B tens bit signals.

 

SRAM

 

            The SRAM in this project is implemented as a bunch of wires in the top module. The SRAM_ADDR is set using the eighteen bit addr_reg register which is assigned by the Cellular automaton visualization unit. The SRAM_DQ is either tri-stated to read out of memory or set to the sixteen bit data_reg register to write the value to memory. The write or read functionality is done with the we register which dictates whether a write to memory is enabled or not. The rest of the wires, such as SRAM_UB_N, SRAM_LB_N, SRAM_CE_N, and SRAM_OE_N are set to zero. The SRAM is used for writing an image to the SRAM and then reading it out onto the VGA display using the Cellular automaton visualization unit.

 

Cellular Automaton Visualization

 

            The Cellular Automaton Visualization is an instantiated processing unit in the top module since the attempt to place it in separate module was unsuccessful. Towards the beginning of this unit is where the reset wire is assigned. The reset is set to ~KEY[0] so that the entire system can be restarted based on the users input. After the reset wire there is one other wire instantiated which is x_low_bit which is used for the pseudo random number generator. The pseudo random number generator which takes a thirty one bit registers (x_rand) and xors the thirteenth and twenty seventh bit together and shifts this value in the bottom of the x_rand. This pseudo random number generator is used to instantiate a random first line for the cellular automaton initial condition to be used to progress the cellular automaton across the screen. The registers created for this visualization were addr_reg, data_reg, we, state, lock, rule, randinit, x_walker, y_walker, and sum. The addr_reg is eighteen bits and used to send address to the SRAM module. The data_reg is sixteen bits and used to send data to the SRAM over the SRAM_DQ bus. The we register is used to dictate the SRAM_WE_N wire and can tell the SRAM whether or not to write the value on the data bus or not. The state register is four bits and is used to move through the state to draw the current cellular automaton image. The lock register is one bit and used to lock in a calculation of another cellular automaton pixel. The rule register is eight bits long and is used to dictate the current cellular automaton rule to implement. The randinit one bit register is used to tell the visualization scheme to start with a random initial condition or not. The x_walker and y_walker registers are both eight bits and are used to traverse the SRAM to write values into SRAM so they can be read appropriately and sent to the VGA display. The final register, sum, is a three bit register which is used to index into the rule to figure out if the pixel currently being looked at is to be colored or made black.

            The Cellular Automaton function runs as an always block on the posedge of the VGA_CTRL_CLK and the first thing done in this section is to sample the audio in and bass, cymbal, and the voice filtered audio signals. These are sampled at both five bits and fifteen bits. These values are used later on for color schemes to be written to the SRAM for display on the VGA display. Upon reset the address register is set to the current coordinates of the VGA controller. The we, data_reg, and rand are set to zero. If the randinit is high or then start the x_walker and y_walker either start in the top left or over by one pixel to draw the intial condition respectively.  The rule on reset is set to one and the state is set to test1. If reset is not pressed then the module will check to see if randinit is pressed and the rand register is high then we assign a random sequence of pixels to the first line of the LCD display. A random line is done by checking the highest bit in the x_rand register and if one it places color in the pixel location and otherwise it makes the pixel black.  After the addr_reg and data_reg are set and we is set to write the value will be written and this short section will increment x_walker until it reaches the end of the line and resets the x_walker and y_walker to the top left corner at (1,0) and sets the randinit low and we high to stop writing memory. If rand is not high then a single pixel in the center of the screen is written as another initial condition possibility. The data written in this cellular automaton is not white or black pixels but pixel color is chosen either from the current audio signals or from a pixel controller unit but when a pixel is filled in the most significant bit is still written in as one and that is used to check for how to fill in the next line on the screen.

            After the randinit section the main state machine can be seen that is run when either the VGA vertical and horizontal sync is active low which reduces the jitter in the image. The state machine then begins where it enters the state test1. This state does not allow a memory write, sets the lock bit high so we know a pixel is being calculated, the sum is reset to zero, the addr_reg is set to the {x_walker, y_walker}, and finally the state is set to test2. In test2 we check the lock bit and if it is not high then we return to start test1. If the lock bit is set then we place the most significant bit of the SRAM_DQ into sum[1] for the first part of the rule offset. The addr_reg is set to {x_walker-1, y_walker} and then the state is set to test3. In test3 Once again the lock bit is tested similarly as before. Once again the SRAM_DQ’s most significant bit is checked and place into sum[2]. The addr_reg is set to {x_walker+1, y_walker} and state is moved to test4. In test four we once again do the lock bit and then SRAM_DQ’s most significant bit is placed in sum[0] and then the state is change to draw_walker. In draw_walker we also check the lock bit and if it is set then we set a memory write the addr_reg is set to {x_walker,y_walker+1}. Next the rule is offset with sum (rule[sum])and if it is one then a pixel combination is written into SRAM based on what the user selected. If the user selectes zere, one, two, three, or four the pixel value written is either sample of all three filter outputs, base filter output, cymbal filter output, voice filter output, or audio inputs. If none of the options before are selected then a pixel controller output is written to SRAM. If the sum offset into rule is not one then a black pixel is written to SRAM.  If the lock bit is not set then the state machine remains in the draw_walker state but if a pixel is written to memory then the update_walker state is entered where the x_walker and y_walker are incremented appropriately across the screen. The x_walker is incremented by one if it is less than 318 and then test1 is returned to. If the x_walker has reached the end of the line or the value 318 then the y_walker is increment if it is less than 237. The x_walker and y_walker are incremented as such until they reach the end of the screen where the user_wait state is entered. In the user_wait state if the user has selected this visualization then SW[1] & SW[12] will be set high. The SW[1] is to select the CA module and the SW[12] is to pause the progression if a cool image has appeared but that is a subjective component on the user end. Also in user wait state the number of CA’s drawn is larger than the maxPeriodLength then it is time to draw a new CA on the screen. The countCA is set to zero and if SW[2] is high then the rule simply increments otherwise the rule is dictate but bits 20 to 13 of the maxPerLength register. If the rule is the max value and SW[2] is high then the rule is reset to one but if not then the maxPerLength bits are used to dictate the rule.  After this the x_walker and y_walker are reset to zero. If rand is high then randinit is set and state is returned to test1. If countCA has not reached the maxPeriodLength then this module remains in the user_wait state until the timer has terminated. Finally if the reset, randinit, or (~VGA_VS | ~VGA_HS) conditions are not met the CA sets the lock bit to zero, sets the memory to read, and set the address register to the coordinates from the VGA unit. This module will display CA’s at the beats of audio input and images of this can be seen below in the results section.

 

Draw Bars

 

            The second visualization module included in this project is draw bars which essentially shows the progression of the audio codec inputs over time. The draw bars module has a lot of inputs as it was actually capable of being placed in a sub module. The inputs into this module are iHeight, iX, iY, iVGA_VS, iVGA_HS, CLK, VGACLK, AUDCLK, CLK27, audIn, bass, cymbal, voice, RST, period, bassH, cymbalH, voiceH, and sigSel. The iHeight, bassH, cymbalH, and voiceH are the all height mapping of the audio_inL, the output from the bass filters, the cymbal filters, and the voice filters after being run through the height mapping module. The iX and iY inputs are the current coordinates coming from the VGA controller and are used to detect which region we are currently writing to. The iVGA_VS and iVGA_HS are the vertical and horizontal sync signals of the VGA controller and are used to reduce jitter, if possible, and know when to redraw the screen.  The CLK is the 50 MHz clock input. The VGACLK is the VGA _CTRL_CLK input. The AUDCLK is the AUD_DACLRCK clock input. The CLK27 is the CLOCK_27 clock input. The audIn, bass, cymbal, and voice inputs are the sixteen bit audio signals from the audio input signal or one of three filters. The RST is the reset from ~KEY[0]. The period is the period of the current waveform. The outputs from this module are the state which was used for debugging and the three ten bit VGA color outputs for red, green, and blue.

            There are also a large number of wires and register declared in this module. The wires red, green, and blue are used for output from the pixel controller module and placed into the output to the VGA controller if the current coordinates of the VGA controller wants are to be colored. The next on the set of wires is one hundred one bit c wires which are used for detection to see if the VGA controller is currently viewing the coordinates within one of the columns to be drawn. After the declaration of the hundred column wires there is the instantiation of one hundred ten bit height registers which are used to keep track of the current magnitude of the waveform and shift that magnitude across the screen as time increases. There is one module instantiated inside of the draw bars and that is the pixelController which is used to cycle through pixel schemes to keep the display fresh and new all the time. After the instantiation of the pixelController all of the column registers are assigned based on the current coordinates from the VGA controller. Each column wire checks to make sure the y coordinate is above the height register value and the x coordinate is between the six pixel bound placed on the current column.  There are also two other wires used in this module to create eyes on the screen. The eyes are two rectangles near the top of the screen and their condition is modified based on either the bottom four bits of height_reg10 or height_reg20 depending on whether it is eye1 or eye2. The conditions checked for the eyes vary the rectangles size with each sample to pace their flashes with the music sampling.  

            The main part of this visualization module is the always block on the positive edge of the 50 MHz clock. In this section if the reset is high then all the height registers are set to zero and the draw_state is set to init. If the reset is not high then a sampleCount is incremented by one on each positive edge of the clock. In the init state if the sampleCount is large than the bottom fourteen bits of the period then new samples of the audio signals are taken. Also the first height register (height_reg0) is set to one of the four height maps inputted into this module. If the user selection is zero, one, two, or three then the height register used is one for the audio input signal, the bass filter output, the cymbal filter output, or the voice filter output respectively. The rest of the init state is shifting all the registers values up one register which allows for the progression of height across the screen. Finally the draw_state is set to color. Then the color state is entered where we check if one of the one hundred column conditions has been met or one of the eye conditions has been met and not when the y coordinate from the VGA controller is divisible by ten. The check to make sure the y coordinate is not divisible by 10 makes the bars discretely different and significantly easier to draw. If this condition is met then the current location from the VGA controller is shaded in with a color which depend on the user input from SW[10:8]. If the switch value is zero then the pixel controller values are outputted and if a value that is not checked comes in then the pixel controller values are outputted. If the switch value is one, two, three, or four then the audio input signal, bass filter output, cymbal filter output, or voice filter output are used to output pixel values respectively. In each case the red is set to the top ten bits of the signal excluding the sign bit, the green is set to the inverse of the 12 to 3 bits, and the blue is set equal to the bottom ten bits. If one of the eye conditions are met and the SW[10:8] is zero then the pixel controller values are used with eye1 using the inverse of blue and eye2 using the inverse of green. If the eye1 and eye2 have five, six, or seven as the selected input then top ten bits without the sign bit are used in the following inverted combinations: bass, cymbal, voice and cymbal, voice, bass and voice, bass, cymbal respectively. If a column or eye condition is not met then a black pixel is sent to the VGA controller. Finally in this module we wait in this state until the vs_sig is set high and then the state moves back to init. The vs_sig register is set to note the completion of the screen drawing which help remove as much jitter from the screen as possible. The vs_sig is set using another state machine on vs_state which waits for the falling edge of the VGA_VS clock to set vs_sig high and then on the next cycle when it goes to state one sets the value back to zero which allows for all the height registers to shift by one and then the screen is drawn. Once the VGA_VS goes high again the state goes back to waiting for the VGA_VS to fall again before shifting the height registers. At the end of this module there are three assignments to output the pixel values on oR, oG, and oB. This module successfully draws the height of the current signal selected across the screen with two fluctuating eyes. Images of this can be seen in the results section below.

 

Simple Visualization

           

            In the filtering section above precise visual synchronization was a direct goal as part of this project. The more complicated abstract visuals seen in the high level design worked out very well but for precise coordination simpler visuals were needed. The simpler visuals were drawn using a module similar to the draw bars module explained above. For the simple visualization module which included the bars module but in the simple module there were only twelve columns that were used and made a simpler version of the draws bars seem above that followed a low passed version of the height mapping. Another visualization scheme used was to draw a floating box on the screen. On each run through of the draw bars state machine the current x. On the other hand the y coordinate was added to by a larger quantity based on the threshold of the music. Essentially the purpose was to have a box gently float back and forth horizontally and when the beats passed over a threshold the y coordinates of the box would be boosted and then slowly fall again when the music did not surpass the threshold. This gave a very good measure of the bass of the music. One final simple scheme used in this lab was to create a single box in the center of the screen and fill it in with green color. The coloring in the box varied, however, with the high frequency of the music so you could get a feeling of the energy of the high frequencies in the music being played. The code for this simple visualization can be found in the appendix.

 

Box Visuals

 

            The third visualization module used is the box visualization which shows the magnitudes of the audio input signal and the output of all three filters implemented in the top module. The inputs into this module are reset, CLK50, AUDCLK, VGA_VS, VGA_HS, audIn, cymbal, bass, voice, coordX, coordY, and period. The reset is the reset from ~KEY[0]. The CLK50, AUDCLK, VGA_VS, and VGA_HS are 50 MHz clock, the audio clock, and the vertical and horizontal sync of the VGA respectively. The audIn, cymbal, bass, and voice inputs are all sixteen bit audio signals from the audio codec and three filters.  The coordX and coordY or the current coordinates from the VGA controller. Finally, period is the current value of maxPerLength from the period calculator. This module only has three outputs which are red, green, and blue which are all ten bit pixel values. The boxVisual module has a number of registers called state, sample, sampleCymbal, sampleBass, sampleVoice, region, redValue, greenValue, blueValue, and audCount. The audCount is used to count a larger number of clock cycles before sampling the audIn, cymbal, bass, and voice signal again to make the visuals do not move too rapidly to destroy the user experience. The sample, sampleCymbal, sampleBass, and sampleVoice are all the registers where the current samples are kept for each of the respective input signals. The region register is used to tell which region on the screen the VGA controller is currently traversing. Where the VGA controller is will dictate what the pixel values that are outputted will be. Finally the redValue, greenValue, and blueValue are all ten bit registers that are set depending on the current region and output from the module to the VGA controller.  Finally this module has twelve wires which are four red lines, four green lines, and four blue lines which are used for the different color outputs of the pixel controller to set four different colors depending on the region. The r0, r1, r2, and r3 wires correspond to regions zero, one, two, and three which really correspond to audio input signal, bass filter out, cymbal filter out, and voice filter out.

            The main part of this module is run on the positive edge of the 50 MHz clock and the first item in this block is the sampling section which was described above with the audCount. Next checking the reset the state is set to locate. If the reset is not high then the locate state is entered. In the locate function the VGA screen is divided up into a grid of rectangle that are each 35 by 48 (y, x) pixels in size with grid blocks on the end truncated if necessary. The purpose of locate is to set the register region to know where we are on the screen. On top of the grid detection there are four large concentric rectangles on the screen. The outer most rectangle visualizes the audio input signal, then the bass filter output, then cymbal filter output, and finally in the center and smallest voice filter output. For each location check we first check what our current X coordinate from the VGA controller is. Then after the X coordinate is checked the Y coordinate is checked and from there we can tell which region we are in. The region can take one of four values (but default cases are provided for assurance) in which zero refers to the audio input signal, one refers to the bass filter output, two refers to the cymbal filter output, and three refers to the voice filter output.  To add some variability in the regions the current column corresponding signal has its four most significant bits (not the sign bit) subtracted from the bounds of the column. This allows for the thickness of each column to change. Furthermore the top and bottom rows of each section also have the same top four bits subtracted from them. As a result each of the four concentric rectangles changes their size differently depending on the magnitude of their respective signal.  Once the region register has been set the state moves to color in which a case statement is used on the region. Depending on the region a different color from a different pixel controller is used to shade in that region. Not only do you have four different regions changing in width and height differently but they also change in color differently. After the appropriate color is placed in the redValue, greenValue, and blueValue registers then the state goes back to locate. If none of the four regions are satisfied the VGA displays black. The ten bit pixel values are output to the top module and into the VGA controller.

           

Pixel Controller  & Pixel Variation

 

            The three visualization units each used this unit’s outputs to for color the pixel values to output to the VGA controller. The goal of this module is to cycle through a variety of schemes and output a long sequence of pixel values that do not repeat frequently. The inputs into this module reset, VGA_VS, VGA_HS, CLK, CLK27, AUDCLK, schemeReset, audIn, and periodIn. The reset is the ~KEY[0] from the top module. The VGA_VS, VGA_HS, CLK, CLK27, and AUDCLK are all basic sync or clocks. The schemeReset however is the value that the pixel controller sets to its schemeCycle register when the hardware is reset. The schemeReset value is used so the controller can start offset within the sequence of pixel values from another pixel variation unit. The audIn in the audio input signal and the periodIn is the period of the current audio signal from the period calculator. This module has three outputs of red, green, and blue which are the pixel values to whatever module instantiated it. The module also has three wires (redValue, greenValue, and blueValue) that grab the pixel values from the pixel variation unit.  This module does have a number of registers called wtPrd, realPeriod, schemeCycle, and schemeCount. The wtPrd dictates the current wait period selection for the pixel variation unit. The real period is the period sent to the pixel variator which compensates for the change in color taking 2^7 cycles and shifts the period down by that much to maintain the colors and bass beat synchronization. The schemeCycle is the current scheme wanted from the pixel variation unit. The schemeCount is the number of clock cycle until the period is reached to increment the scheme to be sent to the pixel variator.

            The main chunk of this unit occurs in the 50 MHz always block on the positive edge where is reset is pressed the schemeCount goes to zero and the schemeCycle is set to the schemeReset value. If the reset is not pressed then the schemeCount increments until it is larger than eight times the period input which allows the user to enjoy a scheme for a long period of time before changing the scheme. Once the schemeCount exceeds its value it increments the schemeCycle by one and checks to see if the schemeCycle is large than 254 and if it is the schemeCycle is set to zero. Also when the schemeCycle reaches its last value the wait period is changed. The wtPrd is incremented which allows for a different count time in the pixel variation unit.  The final operation the pixel controller unit is to shift the periodIn down.

            The pixel variation unit is similar to the pixel controller unit in that it outputs the red, green, and blue pixel values. The inputs into this unit at reset, VGA_VS, CLK, scheme, wtPer, and period. The only inputs that are new here are the scheme and wtPer. The scheme is the schemeCylce from the pixel controller and the wtPer is the waiting period selector from the pixel controller. The scheme value is then dissected into its meaningful values. Reverse, stat, alt, thirdVal, and mode are extracted from the following from scheme as scheme[4], scheme[1], scheme[0], scheme[3:2], and scheme[7:5] respectively. The pixel values in this unit are set on the positive edge of the clock. Upon reset the count and all pixel registers are set to zero. If the reset is not set and when the VGA_VS is low the scheme values are extracted and then parsed into the pixel value wanted. First the wtPrd chooses between how long to count clock cycles till outputting new pixel values to slow the change in color or else it would change too fast and make the users eyes hurt. After the wait period is selected the mode case cased which dictates one of the following schemes in order from zero to seven:  (red up, green down), (blue up, red down), (green up, blue down), (blue up, green down), (green up, red down), (red up, green up), (red up, blue up), and (green up, blue up). Once a mode is selected we wait for the counter to increment past countMax. Once the countMax is surpassed the first color is either added or subtracted depending if reverse is set. Next if the scheme dictates that the second color is stationary that value is checked. If the second color is to be stationary then the second color will cycle by modulo 1000 by increments of 200 if the alternate value is high otherwise it is not manipulated at all. If the second color is not to be stationary the reverse is checked again and the second color is either added or subtracted appropriately. If the second color is not stationary then the third color (third color being the one note mentioned in the modes listed above) is checked as to whether it should alternate or be set by the thirdVal register. If the alternate bit is set high then the third color cycles through module 1000 by increments of 200 else the thirdVal case statement dictate the current value as either zero, 250, 500, or 750.  This logic is simply repeated for all eight modes and then the red, green, and blue registers are outputted on wires and eventually to the VGA controller for one’s viewing pleasure.

 

Software

 

There was no software used in the functionality for our project but Matlab code was used to generate the Draw Bars module since it involved a lot of repetitive lines be created. See the appendix for this code.

 

Testing

Hardware

 

            The assembly of the hardware for our project implementation involved quite a few debugging techniques. The filtering part of the project had several ways to test whether it worked or not. The signal generator was used to input a signal with a known frequency and it was passed into the DE2 board using the audio codec. Once the signal was inside the FPGA it was victim to being manipulated by a large number of filters. Many filters were used and tested and the outputs on the audio codec output were switched using the switches on the DE2 board. Two signals could be checked at the same time using the right and left channels on the output. The signals that were checked on the line out were put into the oscilloscope to see what they looked like. The value of the signal could be display on the red LEDs. The signal generator was also used at this point to confirm how good the cutoffs were and whether the filters were actually working. For example a 47 Hz wave was place on the input channel and was barely seen after the cymbal and voice filters. Although it was still seen after the bass filter.

            The period calculation unit also used a similar technique. In order to confirm the functionality of the period calculator the signal generator output a known frequency and as a result the period could be calculated and the order of magnitude for the number cycles could be found. It was found at first that doing only two zero crosses only resulted in the half period so three zero cross measurements were needed to get the same order of magnitude for our period calculations. The period length was also output on the HEX displays so the value could be updated when the frequency was changed. Indeed when the frequency increased the period displayed decreased. It was also discovered that some error could occur in measuring the period as down sampling from audio rate to one thousand hertz could sometimes shift the zeros around so max periods were kept for more accuracy.

            When first trying to use the audio codec and VGA controller modules it was necessary to use the red LEDs, the green LEDs, the switches, and the HEX displays to be able to display as much information as possible. Problems experienced with these units were undeclared signals and clocks that were required to drive the controlling units. Once these modules work the LEDs and hex displays were still used to display information about the VGA display being updated. For example the Cellular automaton visualization wouldn’t work at first so the coordinates were put on the red LEDs and the state on the green LEDs and it was seen that incrimination of the address halted part way through execution which turned out to be a side effect of having moved the logic into a sub module. There was quite a bit of wasted time during this lab in attempting to take logic that worked perfectly fine in the top module and trying to move that logic into a sub module and having it no longer work. The filters had a known problem of a critical timing error but this did not show for other unit such as the Period Calculator and Cellular Automaton modules that were attempted. Due to the lack of time these large sections of code of were left in the top module. The oscilloscope was also used here to see if the CIC module was work in a sub module but it appeared not to be. Also much time was spent change various critical values inside certain modules to see how the display would change or how closely synchronized the music was with the visualization on the LCD display.

            When creating the visualization modules it was very helpful to try simple algorithms at first and check how they looked visually using the VGA controller and LCD display in the lab. Numerous additions could be made to visualization modules and displayed on the LCD display to fine tune and ensure the correct behavior. Also the use of speakers in the lab allowed us to see that the music was synced up fairly well with the visualizations. The final form of testing that was used for logic that could not be moved to sub modules and for strange behavior over the entire board Signal Tap logic analyzer was used. The signal tap logic analyzer uses M4k blocks to store the values of signals on the FPGA over time. As a result I could keep track of how some of my modules were either not incrementing correctly or a variable was being set incorrectly. Particularly when there are SRAM and VGA display issues Signal Tap will help find the problem quickly.

 

Software

 

            No software was used in our project implementation. The software used was matlab script to write verilog which contained all print statement so if there was an error it was printed in the console and visibly correctible.

 

Results of Design

 

We successfully implemented four different visualizations, depicted in the figure below.  Each visualization runs smoothly with variations dictated by the audio input. The “boxes” visualization consists of several boxes whose size and color is modulated by the audio. Cellular automata visualization draws a random cellular automata rule on a periodic basis depending on the bass frequencies in the audio input.  The bars visualization draws 100 bars, each representing a past sample of the audio input. It also has two boxes near the top of the screen which are intended to appear like “eyes” whose size is modulated by the audio amplitude.  In addition, the color is periodically altered. We also have a simple, single bar visualization. This visualization is intended to show how our internal filtering facilitates video synchronization with the audio. In addition to the bar visualization there is also an LED visual that flashes with the bass beat. One final visualization that moves a single square around the screen back and forth in the horizontal direction. In the vertical direction the square will go higher based on the bass beat and slowly falls when there is no bass in the incoming audio signal.

            The boxes visualization contains some small visual artifacts (not visible in the figure) but otherwise each visualization is displayed as desired. The filters used performed adequately. We were able to extract bass, voice/guitar, and cymbal beats relatively well. Combined with thresholding, our filtering displays relatively accurate synchronization with the music beats. This is especially visible in the single bar visualization.         Our project did not require safety considerations nor did it cause interference with other designs in the lab. The resulting project is usable by anyone, simply connect audio input to the board and use the switches to select a visualization scheme.

 

 

Figure 6: Visualizations – Boxes (Left) – Cellular Automata (Right)

 

Figure 7: More Visualization – Bars (Left) – Single Bar (Right)

 

 

Figure 8: Visualization - Bars (left) – Cellular Automaton (right)

 

Figure 9: Visualization – Cellular Automaton (left) – Box Visual (right)

 

 

Figure 10: Visualization – Cellular Automaton on both screens

 

 

 

 

Conclusion

 

Our goal was to implement audio visualization on the Altera DE2 board. Overall, we have achieved a satisfactory end result.  Six different visualization schemes were implemented: two amplitude modulated bar schemes, one LED mimic, single box, beat triggered cellular automata, and amplitude modulated boxes. In addition, we implemented a filtering scheme to improve visual and audio synchronization.  Our filtering schemes utilized both period and amplitude measurements.

Given more time, we would have liked to explore more sophisticated filtering schemes. We found that for complex visualizations, it was difficult to synchronize the music with the drawing. With an improved filtering scheme, we may have been able to synchronize better. For instance, it would be interesting to explore filtering schemes intended to isolate single instruments from music. More time would have also been helpful because the number of visualization schemes is essentially endless and it would have been enjoyable to spend more time implementing more algorithms.

There are no standard schemes for audio visualization. In fact, we did not find adequate documentation on any specific audio visualization implementation. However, we can compare our audio visualization to others. The Atari Video Music device developed by Atari Inc. in 1976 was one of the first audio visualization devices. We believe that our implementation is comparable to the Atari Video Music device.

Regarding intellectual property, our IIR filters were adapted from those provided on the ECE5760 website. Our code also uses the audio codec driver and VGA driver from the ECE5760 website. Finally, there are no legal considerations to address regarding our project.

 

 

 

 

 

 

APPENDIX

 

/////////////////////////////////////////////////////////////

///////// Audio Visualization ///////////////////////////////

//////// ECE 5760 - Final Project ///////////////////////////

//////// Michael Lyons - mpl56 //////////////////////////////

//////// Darbin Reyes - der34 ///////////////////////////////

/////////////////////////////////////////////////////////////               

wire [31:0]                      mSEG7_DIG;

reg                 [31:0]         Cont;

wire                                     VGA_CTRL_CLK;

wire                                     AUD_CTRL_CLK;

wire [9:0]                         mVGA_R;

wire [9:0]                         mVGA_G;

wire [9:0]                         mVGA_B;

wire [19:0]                      mVGA_ADDR;                                                                //video memory address

wire [9:0]  Coord_X, Coord_Y;    //display coods

wire                                     DLY_RST;

 

assign          TD_RESET                        =                     1'b1;            //                   Allow 27 MHz input

assign          AUD_ADCLRCK             =                     AUD_DACLRCK;

assign          AUD_XCK                          =                     AUD_CTRL_CLK;

 

//modules needs for Audio codec and VGA

Reset_Delay                                                                    r0                   (.iCLK(CLOCK_50),.oRESET(DLY_RST)         );

I2C_AV_Config                                       u3                  (                      //                   Host Side

                                                                                                                                                                        .iCLK(CLOCK_50),

                                                                                                                                                                        .iRST_N(KEY[0]),

                                                                                                                                                                        //                   I2C Side

                                                                                                                                                                        .I2C_SCLK(I2C_SCLK),

                                                                                                                                                                        .I2C_SDAT(I2C_SDAT)                     );

                                                                                                                                                                       

VGA_Audio_PLL                                   p1                  (                      .areset(~DLY_RST),.inclk0(CLOCK_27),.c0(VGA_CTRL_CLK),.c1(AUD_CTRL_CLK),.c2(VGA_CLK)                     );

//////////////////////////////////////////////////////////

// output to audio DAC

wire signed [15:0] audio_outL, audio_outR ;

// input from audio ADC

wire signed [15:0] audio_inL, audio_inR ;

AUDIO_DAC_ADC                                                        u4                  (                      //                   Audio Side

                                                                                                                                                                        .oAUD_BCK(AUD_BCLK),

                                                                                                                                                                        .oAUD_DATA(AUD_DACDAT),

                                                                                                                                                                        .oAUD_LRCK(AUD_DACLRCK),

                                                                                                                                                                        .oAUD_inL(audio_inL), // audio data from ADC

                                                                                                                                                                        .oAUD_inR(audio_inR), // audio data from ADC

                                                                                                                                                                        .iAUD_ADCDAT(AUD_ADCDAT),

                                                                                                                                                                        .iAUD_extL(audio_outL), // audio data to DAC

                                                                                                                                                                        .iAUD_extR(audio_outR), // audio data to DAC

                                                                                                                                                                        //                   Control Signals

                                                                                                         .iCLK_18_4(AUD_CTRL_CLK),

                                                                                                                                                                        .iRST_N(DLY_RST),

                                                                                                                                                                        .isel(SW[17])

                                                                                                                                                                        );

//////////////////////////////////////////////////////////

VGA_Controller                                   u1                  (                      //                   Host Side

                                                                                                                                                                        .iCursor_RGB_EN(4'b0111),

                                                                                                                                                                        .oAddress(mVGA_ADDR),

                                                                                                                                                                        .oCoord_X(Coord_X),

                                                                                                                                                                        .oCoord_Y(Coord_Y),

                                                                                                                                                                        .iRed(mVGA_R),

                                                                                                                                                                        .iGreen(mVGA_G),

                                                                                                                                                                        .iBlue(mVGA_B),

                                                                                                                                                                        //                   VGA Side

                                                                                                                                                                        .oVGA_R(VGA_R),

                                                                                                                                                                        .oVGA_G(VGA_G),

                                                                                                                                                                        .oVGA_B(VGA_B),

                                                                                                                                                                        .oVGA_H_SYNC(VGA_HS),

                                                                                                                                                                        .oVGA_V_SYNC(VGA_VS),

                                                                                                                                                                        .oVGA_SYNC(VGA_SYNC),

                                                                                                                                                                        .oVGA_BLANK(VGA_BLANK),

                                                                                                                                                                        //                   Control Signal

                                                                                                                                                                        .iCLK(VGA_CTRL_CLK),

                                                                                                                                                                        .iRST_N(DLY_RST)     );

 

// assign VGA outputs

assign mVGA_R = SW[1] ? {SRAM_DQ[14:10], 5'b0} : SW[0] ? barR : boxR;

assign mVGA_G = SW[1] ? {SRAM_DQ[9:5], 5'b0} : SW[0] ? barG : boxG;

assign mVGA_B = SW[1] ? {SRAM_DQ[4:0], 5'b0} : SW[0] ? barB : boxB;

///////////////////////////////////////////////////////////////

// SRAM_control

assign SRAM_ADDR = addr_reg;

assign SRAM_DQ = (we)? 16'hzzzz : data_reg ;

assign SRAM_UB_N = 0;                                                                                                                  // hi byte select enabled

assign SRAM_LB_N = 0;                                                                                                                   // lo byte select enabled

assign SRAM_CE_N = 0;                                                                                                                   // chip is enabled

assign SRAM_WE_N = we;                                                                                                             // write when ZERO

assign SRAM_OE_N = 0;                                                                                                                   //output enable is overidden by WE

// reset wire

assign reset = ~KEY[0];

///////////////////////////////////////////////////////////////

//boxvisual instantiation /////////////////////////////////////

wire [9:0] boxR, boxG, boxB;

//module boxVisual(reset, CLK50, AUDCLK, VGA_VS, audIn, cymbal,bass,voice, coordX, coordY, period, red, green, blue);

boxVisual box1(reset, CLOCK_50, AUD_DACLRCK, VGA_VS, VGA_HS, audio_inL,IIR4outL_cymbal2,IIR4outL_bass2,IIR4outL_voice2,Coord_X[9:1],Coord_Y[9:1],maxPerLength,boxR,boxG,boxB);

////////////////////////////////////

// bar pixel values

wire [9:0] barR, barG, barB;

//module drawBars(iHeight,iX,iY,iVGA_VS,iVGA_HS,oR,oG,oB,CLK,VGACLK,AUDCLK,CLK27,audIn,RST,state,period);

//module drawBars(iHeight,iX,iY,iVGA_VS,iVGA_HS,oR,oG,oB,CLK,VGACLK,AUDCLK,CLK27,audIn,RST,state,period,bassH,cymbalH,voiceH,sigSel);

 

drawBars uBars(.iHeight(hbitamp), //draw bars

                                                                                                .iX(Coord_X),

                                                                                                .iY(Coord_Y),

                                                                                                .iVGA_VS(VGA_VS),

                                                                                                .iVGA_HS(VGA_HS),

                                                                                                .oR(barR),

                                                                                                .oG(barG),

                                                                                                .oB(barB),

                                                                                                .CLK(CLOCK_50),

                                                                                                .VGACLK(VGA_CTRL_CLK),

                                                                                                .AUDCLK(AUD_DACLRCK),

                                                                                                .CLK27(CLOCK_27),

                                                                                                .audIn(audio_inL),

                                                                                                .bass(IIR4outL_bass2),

                                                                                                .cymbal(IIR4outL_cymbal2),

                                                                                                .voice(IIR4outL_voice2),

                                                                                                .RST(~KEY[0]),

                                                                                                .state(blank),

                                                                                                .period(maxPerLength),

                                                                                                .bassH(bassHbit),

                                                                                                .cymbalH(cymbalHbit),

                                                                                                .voiceH(voiceHbit),

                                                                                                .sigSel(SW[10:6])

                                                                                                );

////////////////////////////////////////////////

///////////// CA visualization /////////////////

////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////

//most important vars to know about

wire reset;

reg [17:0] addr_reg; //memory address register for SRAM

reg [15:0] data_reg; //memory data register  for SRAM

reg we ;                              //write enable for SRAM

reg [3:0] state;              //state machine

reg lock; //did we stay in sync?

reg [7:0] rule; // to store the CA rule

reg randinit; //signal to init the first line to random black/white

reg [30:0] x_rand;       //shift registers for random number gen 

wire x_low_bit; //rand low bits for SR

reg [8:0] x_walker; //current position coords

reg [8:0] y_walker;

reg [2:0] sum; //neighbors state

///////////////////////////////////////////////////////////////////////

//right-most bit for rand number shift regs

//your basic XOR random # gen

assign x_low_bit = x_rand[27] ^ x_rand[30];

/// pixel controller logic

wire [9:0] CAR, CAG, CAB;

//module pixelController(reset, schemeReset, CLK, CLK27, AUDCLK, VGA_VS, VGA_HS, audIn, periodIn, red, green, blue);

pixelController unit1(reset, 8'd16, CLOCK_50, CLOCK_27, AUDCLK, VGA_VS, VGA_HS, audio_inL, (maxPerLength>>4), CAR, CAG, CAB);

//state names for machines that draws automata

parameter  test1=4'd1, test2=4'd2, test3=4'd3, test4=4'd4,

                        draw_walker=4'd5, update_walker=4'd6, user_wait=4'd7;

//state names for machine tha copies bottom line to top line

parameter cinit=4'd0, cread=4'd1,csave=4'd2, cwrite=4'd3;

reg [31:0] countCA;

reg rand;

reg [4:0] bassColor, cymbalColor, voiceColor;

reg [14:0] bassFull, cymbalFull, voiceFull, audioFull;

// on VGA control clock run CA

always @ (posedge VGA_CTRL_CLK) begin                     

                        bassColor <= IIR4outL_bass2[15:11];

                        cymbalColor <= IIR4outL_cymbal2[15:11];

                        voiceColor <= IIR4outL_voice2[15:11];

                        bassFull <= IIR4outL_bass2[14:0];

                        cymbalFull <= IIR4outL_cymbal2[14:0];

                        voiceFull <= IIR4outL_voice2[14:0];

                        audioFull <= audio_inL[14:0];

                        if (reset)    begin            //synch reset assumes KEY0 is held down 1/60 second

                                                //clear the screen

                                                addr_reg <= {Coord_X[9:1],Coord_Y[9:1]} ;                      // [17:0]

                                                we <= 1'b0;                                                                                                                                                                                             //write some memory

                                                data_reg <= 16'b0;                                                                                                                              //write all zeros (black)                                       

                                                rand <= 1'd0;

                                                if(rand)begin //init top line of screen to random black white

                                                                        x_walker <= 9'd0; //start at 0,0 to make sure every pixel is assign a random color

                                                                        y_walker <= 9'd0;

                                                                        randinit <=1'b1;

                           end else begin

                                                                        x_walker <= 9'd1; //otherwise start one pixexl to the right to force a black border

                                                                        y_walker <= 9'd0;

                                                                        randinit <=1'b1;

                                                                        x_rand <= 31'h55555555;//init random number generator to alternating bits

                                                end

                                                //get rule from switches

                                                rule <= 8'd1;//SW[7:0];

                                                state <= test1;               //first state in drawing state machine

                        end

                        else if(randinit) begin// assign the top line random colors if SW17 is high, else single dot at top center

                                                if(rand) begin//random colors

                                                                        if(x_walker <=9'd319) begin//entire line

                                                                                                x_rand <= {x_rand[29:0], x_low_bit} ; //update the x,y random number gens

                                                                                                addr_reg <= {x_walker,y_walker}; //write to the pixels on the top line

                                                                                                we <= 1'b0; //write

                                                                                                if(x_rand[30]) data_reg <= SW[3] ? {1'b1,bassColor,cymbalColor,voiceColor} : {1'b1,CAR[9:5],CAG[9:5],CAB[9:5]} ; //white pixel

                                                                                                else data_reg <= 16'b0; //black pixel

                                                                                                x_walker <= x_walker+9'd1; //next pixel

                                                                        end else begin

                                                                                                x_walker <= 9'd1;

                                                                                                y_walker <= 9'd0;

                                                                                                we <= 1'b1; //stop writing to mem

                                                                                                randinit<= 1'b0;  //done drawing random line

                                                                        end                                                               

                                                end else begin//single dot at top center

                                                                          addr_reg <= {9'd160,9'd0} ;       //init to single dot

                                                                                                //write a white dot in the middle of the screen

                                                                          we <= 1'b0;                                                                                                                                                                                          

                                                                          data_reg <= {1'b1, CAR[9:5],CAG[9:5],CAB[9:5]}  ;

                                                                          randinit<= 1'b0;

                                                end

                        end else if ((~VGA_VS | ~VGA_HS)) begin //sync is active low //modify display during sync*/

                                                case(state)                      

                                                                        test1: begin//read self

                                                                                                we <= 1'b1;                     //no memory write

                                                                                                lock <= 1'b1;                  //set the interlock to detect end of sync interval

                                                                                                sum <= 3'b0;                                          //init neighbor state                                                                                                

                                                                                                addr_reg <= {x_walker,y_walker};//read  self

                                                                                                state <= test2 ;                                                             

                                                                        end

                                                                       

                                                                        test2: begin//check self and read left neighbor             

                                                                                                if(lock) begin//must check lock before reading to make sure the right value is read

                                                                                                                        we <= 1'b1; //no memory write

                                                                                                                        sum[1] <=SRAM_DQ[15];             

                                                                                                                        //read left neighbor

                                                                                                                        addr_reg <= {x_walker-9'd1,y_walker};

                                                                                                                        state <= test3 ;             

                                                                                                end else state <= test1 ; //otherwise start over because addr_reg was destroyed by VGA controller

                                                                        end

                                                                       

                                                                        test3: begin//check left neighbor and read right neighbor

                                                                                                if(lock)begin

                                                                                                                        we <= 1'b1; //no memory write

                                                                                                                        sum[2] <=SRAM_DQ[15];

                                                                                                                        //read right neighbor

                                                                                                                        addr_reg <= {x_walker+ 9'd1,y_walker };

                                                                                                                        state <= test4 ;                                     

                                                                                                end else state <= test1 ;

                                                                        end

                                                                       

                                                                        test4: begin//check right neighbor

                                                                                                if(lock)begin

                                                                                                                        we <= 1'b1; //no memory write

                                                                                                                        sum[0] <=SRAM_DQ[15];

                                                                                                                        state <= draw_walker ;                                                                  

                                                                                                end else state <= test1 ;

                                                                        end

                                                                       

                                                                        draw_walker: begin//light up cell in next generation

                                                                                                if(lock) begin// if we got this far, then the sum var it correct so spin on the lock until you get a chance to write

                                                                                                                        we <= 1'b0; // memory write                                                                             

                                                                                                                        addr_reg <= {x_walker,y_walker+1'b1}; //cell below this one

                                                                                                                        if(rule[sum])begin

                                                                                                                                                case(SW[5:3])

                                                                                                                                                                        3'd0: data_reg <= {1'b1,bassColor,cymbalColor,voiceColor};

                                                                                                                                                                        3'd1: data_reg <= {1'b1,bassFull};

                                                                                                                                                                        3'd2: data_reg <= {1'b1,cymbalFull};

                                                                                                                                                                        3'd3: data_reg <= {1'b1,voiceFull};

                                                                                                                                                                        3'd4: data_reg <= {1'b1,audioFull};

                                                                                                                                                                        default: data_reg <= {1'b1,CAR[9:5],CAG[9:5],CAB[9:5]} ; //pixel variator unit                                                                                                                                     

                                                                                                                                                endcase

                                                                                                                        end else begin

                                                                                                                                                data_reg <= 16'b0 ; //black

                                                                                                                        end

                                                                                                                        state <= update_walker ; //move to next cell

                                                                                                end else begin

                                                                                                                        state <= draw_walker;

                                                                                                                        lock <= 1'b1;                  //set the interlock to detect end of sync interval

                                                                                                end

                                                                        end

                                                                       

                                                                        update_walker: begin//update the walker

                                                                                                we <= 1'b1; //no mem write

                                                                                                //move to next pixel

                                                                                                if (x_walker<9'd318 & y_walker < 9'd237)begin

                                                                                                                        x_walker <= x_walker+9'd1;

                                                                                                                        state <= test1 ;             

                                                                                                end else if (x_walker == 9'd318 & y_walker < 9'd237)begin

                                                                                                                        x_walker <= 9'd1;

                                                                                                                        y_walker <= y_walker+9'd1;

                                                                                                                        state <= test1 ;             

                                                                                                end else begin               

                                                                                                                         state <= user_wait;//test1 ; //done, just loop

                                                                                                end

                                                                        end

                                                                       

                                                                        user_wait: begin//wait for user to do something

                                                                                                if (SW[1]&SW[12]) begin

                                                                                                                        countCA <= countCA + 32'd1;

                                                                                                                        if (countCA > (maxPerLength)) begin

                                                                                                                                                countCA <= 32'd0;

                                                                                                                                                if (SW[2]) begin

                                                                                                                                                                        rule <= rule + 8'd1;

                                                                                                                                                end else begin

                                                                                                                                                                        rule <= maxPerLength[20:13];

                                                                                                                                                end

                                                                                                                                                if (rule==8'd255) begin

                                                                                                                                                                        if (SW[2]) rule <= 8'd1;

                                                                                                                                                                        else rule <= maxPerLength[20:13];

                                                                                                                                                                        rand <= ~rand;

                                                                                                                                                end

                                                                                                                                                x_walker <= 0;

                                                                                                                                                y_walker <= 0;

                                                                                                                                                if(rand) randinit <= 1'd1;

                                                                                                                                                state <= test1;

                                                                                                                        end

                                                                                                end else begin

                                                                                                                        //randinit <= SW[4];

                                                                                                                        state <= user_wait;

                                                                                                end

                                                                        end

                                                endcase

                        end else begin

                                                //show display when not blanking, which implies we=1 (not enabled); and use VGA module address

                                                lock <= 1'b0; //clear lock if display starts because this destroys mem addr_reg

                                                addr_reg <= {Coord_X[9:1],Coord_Y[9:1]} ;

                                                we <= 1'b1;

                        end

end

// assign the current rule to the green LEDs

assign LEDG = rule;   

assign LEDR = SRAM_DQ;                                                             

//////////////////////////////////////////////

//Period calculation that needs to be done in top module

//parameters

parameter firstCross = 3'd0, secondCross = 3'd1, thirdCross = 3'd2;

parameter firstSample = 3'd3, secondSample = 3'd4, thirdSample = 3'd5;

//registers

reg clk1000;

reg [2:0] state1000;

reg [9:0] newMax;

reg signed [15:0] sample1000, prevSample, hzCount;

reg [31:0] periodCount, periodLength, maxPerLength;

reg signed [15:0] modIn;

//wires

//wire signed [15:0] CIC_out1;

wire signed [15:0] oCIC;

//wire signed [15:0] temp;

//outputs

reg [31:0] period;

// down sample to audio rate

CIC_N2_M1_16bit_fixed f1(oCIC, modIn, CLOCK_27, AUD_DACLRCK, reset);

// sample audio in at 27 MHz

always @ (posedge CLOCK_27) begin

                        modIn <= audio_inL;

end

// period calculation via zero crossing

always @ (posedge CLOCK_50) begin          

                        // bass beat finding

                        periodCount <= periodCount + 32'd1;

                        hzCount <= hzCount + 16'd1;

                        // create a 1000 Hz signal to alias all high freqencies to get

                        // accurate measurements on the lowest frequencies

                        if (hzCount>16'd25000) begin

                                                hzCount <= 16'd0;

                                                if (clk1000) begin

                                                                        clk1000 <= 1'd0;

                                                end else begin

                                                                        clk1000 <= 1'd1;

                                                end

                        end

                        //if reset then set all registers to zero

                        if (reset) begin

                                                maxPerLength <= 0;

                                                prevSample <= 0;

                                                newMax <= 0;

                                                state1000 <= firstSample;

                        end else begin

                                                case(state1000)

                                                                        // on high 1000 Hz take sample of CIC filter output

                                                                        firstSample: begin

                                                                                                if (clk1000) begin

                                                                                                                        sample1000 <= oCIC;//CIC_out1;

                                                                                                                        state1000 <= firstCross;

                                                                                                end

                                                                        end

                                                                        // wait for a sign change in the CIC output

                                                                        firstCross: begin

                                                                                                // if there is a change from positive to negative go to next sample

                                                                                                if((prevSample>0)&&(0>sample1000))begin

                                                                                                                        periodCount <= 32'd0;

                                                                                                                        prevSample <= sample1000;

                                                                                                                        state1000 <= secondSample;

                                                                                                // if there is a change from negative to positive go to next sample

                                                                                                end else if ((prevSample<0)&&(0<sample1000))begin

                                                                                                                        periodCount <= 32'd0;

                                                                                                                        prevSample <= sample1000;

                                                                                                                        state1000 <= secondSample;

                                                                                                end else begin // no change get a new sample

                                                                                                                        prevSample <= sample1000;

                                                                                                                        state1000 <= firstSample;

                                                                                                end

                                                                        end

                                                                        // on high 1000 Hz take sample of CIC filter output

                                                                        secondSample: begin

                                                                                                if (clk1000) begin

                                                                                                                        sample1000 <= oCIC;//CIC_out1;

                                                                                                                        state1000 <= secondCross;

                                                                                                end

                                                                        end

                                                                        // wait for a sign change in the CIC output

                                                                        // second cross for mid way through waveform

                                                                        secondCross: begin

                                                                                                // if there is a change from positive to negative go to next sample

                                                                                                if((prevSample>0)&&(0>sample1000))begin                                                                                                                

                                                                                                                        prevSample <= sample1000;

                                                                                                                        state1000 <= thirdSample;

                                                                                                // if there is a change from negative to positive go to next sample

                                                                                                end else if ((prevSample<0)&&(0<sample1000))begin

                                                                                                                        prevSample <= sample1000;

                                                                                                                        state1000 <= thirdSample;

                                                                                                end else begin // no change get a new sample

                                                                                                                        prevSample <= sample1000;

                                                                                                                        state1000 <= secondSample;

                                                                                                end

                                                                        end

                                                                        // on high 1000 Hz take sample of CIC filter output

                                                                        thirdSample: begin

                                                                                                if (clk1000) begin

                                                                                                                        sample1000 <= oCIC;//CIC_out1;

                                                                                                                        state1000 <= thirdCross;

                                                                                                end

                                                                        end

                                                                        // wait for a sign change in the CIC output

                                                                        // third cross for full period measurement

                                                                        thirdCross: begin

                                                                                                // if there is a change from positive to negative go to next sample

                                                                                                if((prevSample>0)&&(0>sample1000))begin                

                                                                                                                        periodLength <= periodCount;

                                                                                                                        newMax <= newMax + 10'd1;

                                                                                                                        if(newMax > 10'd1000)begin // get a new max period length

                                                                                                                                                newMax <= 10'd0;

                                                                                                                                                maxPerLength <= 32'd1000;

                                                                                                                        end else      if(periodLength > maxPerLength) begin // if new period is larger save it

                                                                                                                                                maxPerLength <= periodLength;

                                                                                                                        end

                                                                                                                        prevSample <= sample1000;

                                                                                                                        state1000 <= firstSample;

                                                                                                // if there is a change from negative to positive go to next sample

                                                                                                end else if ((prevSample<0)&&(0<sample1000))begin

                                                                                                                        periodLength <= periodCount;

                                                                                                                        newMax <= newMax + 10'd1;

                                                                                                                        if(newMax > 10'd1000)begin // get a new max period length

                                                                                                                                                newMax <= 10'd0;

                                                                                                                                                maxPerLength <= 32'd1000;

                                                                                                                        end else      if(periodLength > maxPerLength) begin// if new period is larger save it

                                                                                                                                                maxPerLength <= periodLength;

                                                                                                                        end

                                                                                                                        prevSample <= sample1000;

                                                                                                                        state1000 <= firstSample;

                                                                                                end else begin // no change get a new sample

                                                                                                                        prevSample <= sample1000;

                                                                                                                        state1000 <= thirdSample;

                                                                                                end

                                                                        end                                       

                                                endcase

                        end//

end// end always

// assign which signal you want to output

reg [15:0] audOut;

always @ (posedge CLOCK_50) begin

                        case(SW[16:14])

                                                3'd0: begin

                                                                        audOut <= oCIC; // output the CIC filter

                                                end

                                                3'd1: begin

                                                                        audOut <= audio_inL; // normal audio input

                                                end

                                                3'd2: begin

                                                                        audOut <= IIR4outL_cymbal2; // cymbal filter output

                                                end

                                                3'd3: begin

                                                                        audOut <= IIR4outL_bass2; // bass filter output

                                                end

                                                3'd4: begin

                                                                        audOut <= IIR4outL_voice2; // voice filter output

                                                end

                                                3'd5: begin

                                                                        audOut <= sample1000;

                                                end

                                                default audOut <= 16'd0;

                        endcase

end

// audio outputs assign to wires

assign audio_outL = audOut;//CIC_out1;

assign audio_outR = audOut;

// max period length calculation counter displayed on red LEDs

//assign LEDR = newMax;

///////////////////////////////////////////////////////////////////

/////////////////// absolute value unit ///////////////////////////

///////////////////////////////////////////////////////////////////

wire signed [15:0] absoutL; // output of abs unit

wire signed [15:0] absBass, absCymbal, absVoice;

abs uabsL(absoutL, audio_outR, 4'd0,AUD_DACLRCK); //takes absolute value of input

abs absbass(absBass, IIR4outL_bass2, 4'd0,AUD_DACLRCK);

abs abscymbal(absCymbal, IIR4outL_cymbal2, 4'd0,AUD_DACLRCK);

abs absvoice(absVoice, IIR4outL_voice2, 4'd0,AUD_DACLRCK);

///////////////////////////////////////////////////////////////////

////////////////////// find the highest order bit /////////////////

///////////////////////////////////////////////////////////////////

// highest order bit output

wire [9:0] hbitamp, bassHbit, cymbalHbit, voiceHbit;

firstHbit hb(absoutL[15:6],hbitamp,CLOCK_50); //bit quatize bar height

firstHbit hbbass(absBass[15:6],bassHbit,CLOCK_50); //bit quatize bar height

firstHbit hbcymbal(absCymbal[15:6],cymbalHbit,CLOCK_50); //bit quatize bar height

firstHbit hbvoice(absVoice[15:6],voiceHbit,CLOCK_50); //bit quatize bar height

///////////////////////////////////////////////////////////////////

/////////////////////// 7 segment displays ////////////////////////

///////////////////////////////////////////////////////////////////

HexDigit h0(HEX0, maxPerLength[3:0]);

HexDigit h1(HEX1, maxPerLength[7:4]);

HexDigit h2(HEX2, maxPerLength[11:8]);

HexDigit h3(HEX3, maxPerLength[15:12]);

HexDigit h4(HEX4, maxPerLength[19:16]);

HexDigit h5(HEX5, maxPerLength[23:20]);

HexDigit h6(HEX6, maxPerLength[27:24]);

HexDigit h7(HEX7, maxPerLength[31:28]);

///////////////////////// Filter outputs declared /////////////////

wire signed [15:0] IIR4outL_voice1,IIR4outL_voice2;

wire signed [15:0] IIR4outL_cymbal1,IIR4outL_cymbal2;

wire signed [15:0] IIR4outL_bass1,IIR4outL_bass2;

///////////////////////////////////////////////////////////////////

/////////////////////// cymbal filtering //////////////////////////

/////////////////Filter: cutoff=0.5 ,cheby1 high //////////////////

///////////////////////////////////////////////////////////////////

IIR4_18bit_fixed  IIR4L_cymb1(

     .audio_out (IIR4outL_cymbal1),

     .audio_in (audio_inL),

     .scale (3'd1),

     .b1 (18'hCA7),

     .b2 (18'h3CD63),

     .b3 (18'h4BEC),

     .b4 (18'h3CD63),

     .b5 (18'hCA7),

     .a2 (18'h3FC41),

     .a3 (18'h3A7AA),

     .a4 (18'h3EE8D),

     .a5 (18'h3F654), 

     .state_clk(AUD_CTRL_CLK),

     .lr_clk(AUD_DACLRCK),

     .reset(reset)

) ; //end filter

///////////////////////////////////////////////////////////////////

//////////////// Filter: cutoff=0.6 ,cheby1 low ///////////////////

///////////////////////////////////////////////////////////////////

IIR4_18bit_fixed IIR4L_cymb2(

     .audio_out (IIR4outL_cymbal2),

     .audio_in (IIR4outL_cymbal1),

     .scale (3'd1),

    .b1 (18'h1682),

     .b2 (18'h5A0A),

     .b3 (18'h8710),

     .b4 (18'h5A0A),

     .b5 (18'h1682),

     .a2 (18'h398AF),

     .a3 (18'h395A5),

     .a4 (18'h3EE6B),

     .a5 (18'h3F6EC),

     .state_clk(AUD_CTRL_CLK),

     .lr_clk(AUD_DACLRCK),

     .reset(reset)

) ; //end filter

///////////////////////////////////////////////////////////////////

/////////////////bass beat filter//////////////////////////////////

///////// Filter: cutoff=0.02 , cheby1 low ////////////////////////

///////////////////////////////////////////////////////////////////

IIR4_27bit IIR4_bass1(

     .audio_out (IIR4outL_bass2),

     .audio_in (audio_inL),

    .scale (3'd2),

     .b1 (27'hF),

     .b2 (27'h3E),

     .b3 (27'h5D),

     .b4 (27'h3E),

     .b5 (27'hF),

     .a2 (27'hF492E6),

     .a3 (27'h6A0C0AB),

     .a4 (27'hE0AA7A),

     .a5 (27'h7CA00F9),

     .state_clk(AUD_CTRL_CLK),

     .lr_clk(AUD_DACLRCK),

     .reset(reset)

) ; //end filter

///////////////////////////////////////////////////////////////////

//////////////////////////guitar/voice filter//////////////////////

////////////////// Filter: cutoff=0.05 ,cheby1 high ///////////////

///////////////////////////////////////////////////////////////////

IIR4_27bit  IIR4_voice1(

     .audio_out (IIR4outL_voice1),

     .audio_in (audio_inL),

    .scale (3'd2),

     .b1 (27'h3426B9),

     .b2 (27'h72F651C),

     .b3 (27'h138E856),

     .b4 (27'h72F651C),

     .b5 (27'h3426B9),

     .a2 (27'hE7331D),

     .a3 (27'h6C586C9),

     .a4 (27'hBED26A),

     .a5 (27'h7D469AF),

     .state_clk(AUD_CTRL_CLK),

     .lr_clk(AUD_DACLRCK),

     .reset(reset)

) ; //end filter

///////////////////////////////////////////////////////////////////

/////////////// Filter: cutoff=0.06 ,cheby1 low ///////////////////

///////////////////////////////////////////////////////////////////

IIR4_27bit IIR4_voice2(

     .audio_out (IIR4outL_voice2),

     .audio_in (IIR4outL_voice1),

     .scale (3'd2),

     .b1 (27'hE5),

     .b2 (27'h395),

     .b3 (27'h560),

     .b4 (27'h395),

     .b5 (27'hE5),

     .a2 (27'hE8252D),

     .a3 (27'h6C15AFD),

     .a4 (27'hC401F3),

     .a5 (27'h7D26F62),

     .state_clk(AUD_CTRL_CLK),

     .lr_clk(AUD_DACLRCK),

     .reset(reset)

) ; //end filter

///////////////////////////////////////////////////////////////////

endmodule //top module

///////////////////////////////////////////////////////////////////

//////////////////// draw bars visualization //////////////////////

////////////////////////////////////draw bars//////////////////////

module drawBars(iHeight,iX,iY,iVGA_VS,iVGA_HS,oR,oG,oB,CLK,VGACLK,AUDCLK,CLK27,audIn,bass,cymbal,voice,RST,state,period,bassH,cymbalH,voiceH,sigSel);

// parameters

parameter init=4'd0, color=4'd1,eyeheight=10'd20,eyewidth=10'd60;

// inputs

input [4:0] sigSel;

input [9:0] iHeight, bassH, cymbalH, voiceH; //height of bar

input [9:0] iY; //VGA coordinates

input [9:0] iX;

input [31:0] period;

input [15:0] audIn, bass, cymbal,voice;

input CLK,RST,VGACLK, AUDCLK, CLK27;

input iVGA_VS,iVGA_HS; //vga sync

//outputs

output [3:0] state;

output [9:0] oR,oG,oB; //vga colors

//wires

wire eye1,eye2;

wire [9:0] red, green, blue;

// all column wires declared

wire c0,c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13,c14,c15,c16,c17,c18,c19,c20,c21,c22,c23,c24,c25,c26,c27,c28,c29,c30,c31,c32,c33,c34,c35,c36,c37,c38,c39,c40,c41,c42,c43,c44,c45,c46,c47,c48,c49,c50,c51,c52,c53,c54,c55,c56,c57,c58,c59,c60,c61,c62,c63,c64,c65,c66,c67,c68,c69,c70,c71,c72,c73,c74,c75,c76,c77,c78,c79,c80,c81,c82,c83,c84,c85,c86,c87,c88,c89,c90,c91,c92,c93,c94,c95,c96,c97,c98,c99;

//registers

reg [9:0] reg_R,reg_G,reg_B,x,y;

reg [15:0] sampleAudio, sampleBass, sampleCymbal, sampleVoice;

reg switchColor;

reg [23:0] sampleCount;

reg [3:0] draw_state;

reg [9:0] redValue, greenValue, blueValue;

// all heights registers declared

reg [9:0] height_reg0;

reg [9:0] height_reg1;

reg [9:0] height_reg2;

reg [9:0] height_reg3;

reg [9:0] height_reg4;

reg [9:0] height_reg5;

reg [9:0] height_reg6;

reg [9:0] height_reg7;

reg [9:0] height_reg8;

reg [9:0] height_reg9;

reg [9:0] height_reg10;

reg [9:0] height_reg11;

reg [9:0] height_reg12;

reg [9:0] height_reg13;

reg [9:0] height_reg14;

reg [9:0] height_reg15;

reg [9:0] height_reg16;

reg [9:0] height_reg17;

reg [9:0] height_reg18;

reg [9:0] height_reg19;

reg [9:0] height_reg20;

reg [9:0] height_reg21;

reg [9:0] height_reg22;

reg [9:0] height_reg23;

reg [9:0] height_reg24;

reg [9:0] height_reg25;

reg [9:0] height_reg26;

reg [9:0] height_reg27;

reg [9:0] height_reg28;

reg [9:0] height_reg29;

reg [9:0] height_reg30;

reg [9:0] height_reg31;

reg [9:0] height_reg32;

reg [9:0] height_reg33;

reg [9:0] height_reg34;

reg [9:0] height_reg35;

reg [9:0] height_reg36;

reg [9:0] height_reg37;

reg [9:0] height_reg38;

reg [9:0] height_reg39;

reg [9:0] height_reg40;

reg [9:0] height_reg41;

reg [9:0] height_reg42;

reg [9:0] height_reg43;

reg [9:0] height_reg44;

reg [9:0] height_reg45;

reg [9:0] height_reg46;

reg [9:0] height_reg47;

reg [9:0] height_reg48;

reg [9:0] height_reg49;

reg [9:0] height_reg50;

reg [9:0] height_reg51;

reg [9:0] height_reg52;

reg [9:0] height_reg53;

reg [9:0] height_reg54;

reg [9:0] height_reg55;

reg [9:0] height_reg56;

reg [9:0] height_reg57;

reg [9:0] height_reg58;

reg [9:0] height_reg59;

reg [9:0] height_reg60;

reg [9:0] height_reg61;

reg [9:0] height_reg62;

reg [9:0] height_reg63;

reg [9:0] height_reg64;

reg [9:0] height_reg65;

reg [9:0] height_reg66;

reg [9:0] height_reg67;

reg [9:0] height_reg68;

reg [9:0] height_reg69;

reg [9:0] height_reg70;

reg [9:0] height_reg71;

reg [9:0] height_reg72;

reg [9:0] height_reg73;

reg [9:0] height_reg74;

reg [9:0] height_reg75;

reg [9:0] height_reg76;

reg [9:0] height_reg77;

reg [9:0] height_reg78;

reg [9:0] height_reg79;

reg [9:0] height_reg80;

reg [9:0] height_reg81;

reg [9:0] height_reg82;

reg [9:0] height_reg83;

reg [9:0] height_reg84;

reg [9:0] height_reg85;

reg [9:0] height_reg86;

reg [9:0] height_reg87;

reg [9:0] height_reg88;

reg [9:0] height_reg89;

reg [9:0] height_reg90;

reg [9:0] height_reg91;

reg [9:0] height_reg92;

reg [9:0] height_reg93;

reg [9:0] height_reg94;

reg [9:0] height_reg95;

reg [9:0] height_reg96;

reg [9:0] height_reg97;

reg [9:0] height_reg98;

reg [9:0] height_reg99;

//pixelVar unit1(reset, iVGA_VS, CLK, switch[10:8], switch[7], switch[6:5], switch[4:3], switch[2], switch[1], switch[0], red, green, blue);

//pixelController(reset, CLK, CLK27, AUDCLK, VGA_VS, audIn, periodIn, red, green, blue);

pixelController unit1(reset, 8'd16, CLK, CLK27, AUDCLK, iVGA_VS, iVGA_HS, audIn, period, red, green, blue);

// all column values

assign c0=iY > height_reg0 & iX>10'd0 & iX<10'd6;

assign c1=iY > height_reg1 & iX>10'd6 & iX<10'd12;

assign c2=iY > height_reg2 & iX>10'd12 & iX<10'd18;

assign c3=iY > height_reg3 & iX>10'd18 & iX<10'd24;

assign c4=iY > height_reg4 & iX>10'd24 & iX<10'd30;

assign c5=iY > height_reg5 & iX>10'd30 & iX<10'd36;

assign c6=iY > height_reg6 & iX>10'd36 & iX<10'd42;

assign c7=iY > height_reg7 & iX>10'd42 & iX<10'd48;

assign c8=iY > height_reg8 & iX>10'd48 & iX<10'd54;

assign c9=iY > height_reg9 & iX>10'd54 & iX<10'd60;

assign c10=iY > height_reg10 & iX>10'd60 & iX<10'd66;

assign c11=iY > height_reg11 & iX>10'd66 & iX<10'd72;

assign c12=iY > height_reg12 & iX>10'd72 & iX<10'd78;

assign c13=iY > height_reg13 & iX>10'd78 & iX<10'd84;

assign c14=iY > height_reg14 & iX>10'd84 & iX<10'd90;

assign c15=iY > height_reg15 & iX>10'd90 & iX<10'd96;

assign c16=iY > height_reg16 & iX>10'd96 & iX<10'd102;

assign c17=iY > height_reg17 & iX>10'd102 & iX<10'd108;

assign c18=iY > height_reg18 & iX>10'd108 & iX<10'd114;

assign c19=iY > height_reg19 & iX>10'd114 & iX<10'd120;

assign c20=iY > height_reg20 & iX>10'd120 & iX<10'd126;

assign c21=iY > height_reg21 & iX>10'd126 & iX<10'd132;

assign c22=iY > height_reg22 & iX>10'd132 & iX<10'd138;

assign c23=iY > height_reg23 & iX>10'd138 & iX<10'd144;

assign c24=iY > height_reg24 & iX>10'd144 & iX<10'd150;

assign c25=iY > height_reg25 & iX>10'd150 & iX<10'd156;

assign c26=iY > height_reg26 & iX>10'd156 & iX<10'd162;

assign c27=iY > height_reg27 & iX>10'd162 & iX<10'd168;

assign c28=iY > height_reg28 & iX>10'd168 & iX<10'd174;

assign c29=iY > height_reg29 & iX>10'd174 & iX<10'd180;

assign c30=iY > height_reg30 & iX>10'd180 & iX<10'd186;

assign c31=iY > height_reg31 & iX>10'd186 & iX<10'd192;

assign c32=iY > height_reg32 & iX>10'd192 & iX<10'd198;

assign c33=iY > height_reg33 & iX>10'd198 & iX<10'd204;

assign c34=iY > height_reg34 & iX>10'd204 & iX<10'd210;

assign c35=iY > height_reg35 & iX>10'd210 & iX<10'd216;

assign c36=iY > height_reg36 & iX>10'd216 & iX<10'd222;

assign c37=iY > height_reg37 & iX>10'd222 & iX<10'd228;

assign c38=iY > height_reg38 & iX>10'd228 & iX<10'd234;

assign c39=iY > height_reg39 & iX>10'd234 & iX<10'd240;

assign c40=iY > height_reg40 & iX>10'd240 & iX<10'd246;

assign c41=iY > height_reg41 & iX>10'd246 & iX<10'd252;

assign c42=iY > height_reg42 & iX>10'd252 & iX<10'd258;

assign c43=iY > height_reg43 & iX>10'd258 & iX<10'd264;

assign c44=iY > height_reg44 & iX>10'd264 & iX<10'd270;

assign c45=iY > height_reg45 & iX>10'd270 & iX<10'd276;

assign c46=iY > height_reg46 & iX>10'd276 & iX<10'd282;

assign c47=iY > height_reg47 & iX>10'd282 & iX<10'd288;

assign c48=iY > height_reg48 & iX>10'd288 & iX<10'd294;

assign c49=iY > height_reg49 & iX>10'd294 & iX<10'd300;

assign c50=iY > height_reg50 & iX>10'd300 & iX<10'd306;

assign c51=iY > height_reg51 & iX>10'd306 & iX<10'd312;

assign c52=iY > height_reg52 & iX>10'd312 & iX<10'd318;

assign c53=iY > height_reg53 & iX>10'd318 & iX<10'd324;

assign c54=iY > height_reg54 & iX>10'd324 & iX<10'd330;

assign c55=iY > height_reg55 & iX>10'd330 & iX<10'd336;

assign c56=iY > height_reg56 & iX>10'd336 & iX<10'd342;

assign c57=iY > height_reg57 & iX>10'd342 & iX<10'd348;

assign c58=iY > height_reg58 & iX>10'd348 & iX<10'd354;

assign c59=iY > height_reg59 & iX>10'd354 & iX<10'd360;

assign c60=iY > height_reg60 & iX>10'd360 & iX<10'd366;

assign c61=iY > height_reg61 & iX>10'd366 & iX<10'd372;

assign c62=iY > height_reg62 & iX>10'd372 & iX<10'd378;

assign c63=iY > height_reg63 & iX>10'd378 & iX<10'd384;

assign c64=iY > height_reg64 & iX>10'd384 & iX<10'd390;

assign c65=iY > height_reg65 & iX>10'd390 & iX<10'd396;

assign c66=iY > height_reg66 & iX>10'd396 & iX<10'd402;

assign c67=iY > height_reg67 & iX>10'd402 & iX<10'd408;

assign c68=iY > height_reg68 & iX>10'd408 & iX<10'd414;

assign c69=iY > height_reg69 & iX>10'd414 & iX<10'd420;

assign c70=iY > height_reg70 & iX>10'd420 & iX<10'd426;

assign c71=iY > height_reg71 & iX>10'd426 & iX<10'd432;

assign c72=iY > height_reg72 & iX>10'd432 & iX<10'd438;

assign c73=iY > height_reg73 & iX>10'd438 & iX<10'd444;

assign c74=iY > height_reg74 & iX>10'd444 & iX<10'd450;

assign c75=iY > height_reg75 & iX>10'd450 & iX<10'd456;

assign c76=iY > height_reg76 & iX>10'd456 & iX<10'd462;

assign c77=iY > height_reg77 & iX>10'd462 & iX<10'd468;

assign c78=iY > height_reg78 & iX>10'd468 & iX<10'd474;

assign c79=iY > height_reg79 & iX>10'd474 & iX<10'd480;

assign c80=iY > height_reg80 & iX>10'd480 & iX<10'd486;

assign c81=iY > height_reg81 & iX>10'd486 & iX<10'd492;

assign c82=iY > height_reg82 & iX>10'd492 & iX<10'd498;

assign c83=iY > height_reg83 & iX>10'd498 & iX<10'd504;

assign c84=iY > height_reg84 & iX>10'd504 & iX<10'd510;

assign c85=iY > height_reg85 & iX>10'd510 & iX<10'd516;

assign c86=iY > height_reg86 & iX>10'd516 & iX<10'd522;

assign c87=iY > height_reg87 & iX>10'd522 & iX<10'd528;

assign c88=iY > height_reg88 & iX>10'd528 & iX<10'd534;

assign c89=iY > height_reg89 & iX>10'd534 & iX<10'd540;

assign c90=iY > height_reg90 & iX>10'd540 & iX<10'd546;

assign c91=iY > height_reg91 & iX>10'd546 & iX<10'd552;

assign c92=iY > height_reg92 & iX>10'd552 & iX<10'd558;

assign c93=iY > height_reg93 & iX>10'd558 & iX<10'd564;

assign c94=iY > height_reg94 & iX>10'd564 & iX<10'd570;

assign c95=iY > height_reg95 & iX>10'd570 & iX<10'd576;

assign c96=iY > height_reg96 & iX>10'd576 & iX<10'd582;

assign c97=iY > height_reg97 & iX>10'd582 & iX<10'd588;

assign c98=iY > height_reg98 & iX>10'd588 & iX<10'd594;

assign c99=iY > height_reg99 & iX>10'd594 & iX<10'd600;

//eye tracking

assign eye1= iY >10'd40-height_reg10[4:0] & iY <10'd40+eyeheight+height_reg10[4:0] & iX >10'd140-height_reg10[4:0] & iX <10'd140+eyewidth+height_reg10[4:0];

assign eye2= iY >10'd40-height_reg20[4:0] & iY <10'd40+eyeheight+height_reg20[4:0] & iX >10'd480-height_reg20[4:0] & iX <10'd480+eyewidth+height_reg20[4:0];

 

always @ (posedge CLK) begin

                        if(RST) begin //reset

                                                switchColor<=0;

                                                draw_state<=init;

                                                height_reg0<=0;

                                                height_reg1<=0;

                                                height_reg2<=0;

                                                height_reg3<=0;

                                                height_reg4<=0;

                                                height_reg5<=0;

                                                height_reg6<=0;

                                                height_reg7<=0;

                                                height_reg8<=0;

                                                height_reg9<=0;

                                                height_reg10<=0;

                                                height_reg11<=0;

                                                height_reg12<=0;

                                                height_reg13<=0;

                                                height_reg14<=0;

                                                height_reg15<=0;

                                                height_reg16<=0;

                                                height_reg17<=0;

                                                height_reg18<=0;

                                                height_reg19<=0;

                                                height_reg20<=0;

                                                height_reg21<=0;

                                                height_reg22<=0;

                                                height_reg23<=0;

                                                height_reg24<=0;

                                                height_reg25<=0;

                                                height_reg26<=0;

                                                height_reg27<=0;

                                                height_reg28<=0;

                                                height_reg29<=0;

                                                height_reg30<=0;

                                                height_reg31<=0;

                                                height_reg32<=0;

                                                height_reg33<=0;

                                                height_reg34<=0;

                                                height_reg35<=0;

                                                height_reg36<=0;

                                                height_reg37<=0;

                                                height_reg38<=0;

                                                height_reg39<=0;

                                                height_reg40<=0;

                                                height_reg41<=0;

                                                height_reg42<=0;

                                                height_reg43<=0;

                                                height_reg44<=0;

                                                height_reg45<=0;

                                                height_reg46<=0;

                                                height_reg47<=0;

                                                height_reg48<=0;

                                                height_reg49<=0;

                                                height_reg50<=0;

                                                height_reg51<=0;

                                                height_reg52<=0;

                                                height_reg53<=0;

                                                height_reg54<=0;

                                                height_reg55<=0;

                                                height_reg56<=0;

                                                height_reg57<=0;

                                                height_reg58<=0;

                                                height_reg59<=0;

                                                height_reg60<=0;

                                                height_reg61<=0;

                                                height_reg62<=0;

                                                height_reg63<=0;

                                                height_reg64<=0;

                                                height_reg65<=0;

                                                height_reg66<=0;

                                                height_reg67<=0;

                                                height_reg68<=0;

                                                height_reg69<=0;

                                                height_reg70<=0;

                                                height_reg71<=0;

                                                height_reg72<=0;

                                                height_reg73<=0;

                                                height_reg74<=0;

                                                height_reg75<=0;

                                                height_reg76<=0;

                                                height_reg77<=0;

                                                height_reg78<=0;

                                                height_reg79<=0;

                                                height_reg80<=0;

                                                height_reg81<=0;

                                                height_reg82<=0;

                                                height_reg83<=0;

                                                height_reg84<=0;

                                                height_reg85<=0;

                                                height_reg86<=0;

                                                height_reg87<=0;

                                                height_reg88<=0;

                                                height_reg89<=0;

                                                height_reg90<=0;

                                                height_reg91<=0;

                                                height_reg92<=0;

                                                height_reg93<=0;

                                                height_reg94<=0;

                                                height_reg95<=0;

                                                height_reg96<=0;

                                                height_reg97<=0;

                                                height_reg98<=0;

                                                height_reg99<=0;

                        end

                        else begin

                                                sampleCount <= sampleCount + 24'd1;

                                                case(draw_state)                               

                                                init: begin

                                                                        if(sampleCount > period[13:0])begin

                                                                                                sampleCount <= 24'd0;

                                                                                                sampleAudio <= audIn;

                                                                                                sampleBass <= bass;

                                                                                                sampleCymbal <= cymbal;

                                                                                                sampleVoice <= voice;

                                                                        end

                                                                        case(sigSel[1:0])

                                                                                                2'd0: height_reg0 <= 10'd479-iHeight;

                                                                                                2'd1: height_reg0 <= 10'd479-bassH;

                                                                                                2'd2: height_reg0 <= 10'd479-cymbalH;

                                                                                                2'd3: height_reg0 <= 10'd479-voiceH;

                                                                        endcase

                                                                        height_reg1 <= height_reg0;

                                                                        height_reg2 <= height_reg1;

                                                                        height_reg3 <= height_reg2;

                                                                        height_reg4 <= height_reg3;

                                                                        height_reg5 <= height_reg4;

                                                                        height_reg6 <= height_reg5;

                                                                        height_reg7 <= height_reg6;

                                                                        height_reg8 <= height_reg7;

                                                                        height_reg9 <= height_reg8;

                                                                        height_reg10 <= height_reg9;

                                                                        height_reg11 <= height_reg10;

                                                                        height_reg12 <= height_reg11;

                                                                        height_reg13 <= height_reg12;

                                                                        height_reg14 <= height_reg13;

                                                                        height_reg15 <= height_reg14;

                                                                        height_reg16 <= height_reg15;

                                                                        height_reg17 <= height_reg16;

                                                                        height_reg18 <= height_reg17;

                                                                        height_reg19 <= height_reg18;

                                                                        height_reg20 <= height_reg19;

                                                                        height_reg21 <= height_reg20;

                                                                        height_reg22 <= height_reg21;

                                                                        height_reg23 <= height_reg22;

                                                                        height_reg24 <= height_reg23;

                                                                        height_reg25 <= height_reg24;

                                                                        height_reg26 <= height_reg25;

                                                                        height_reg27 <= height_reg26;

                                                                        height_reg28 <= height_reg27;

                                                                        height_reg29 <= height_reg28;

                                                                        height_reg30 <= height_reg29;

                                                                        height_reg31 <= height_reg30;

                                                                        height_reg32 <= height_reg31;

                                                                        height_reg33 <= height_reg32;

                                                                        height_reg34 <= height_reg33;

                                                                        height_reg35 <= height_reg34;

                                                                        height_reg36 <= height_reg35;

                                                                        height_reg37 <= height_reg36;

                                                                        height_reg38 <= height_reg37;

                                                                        height_reg39 <= height_reg38;

                                                                        height_reg40 <= height_reg39;

                                                                        height_reg41 <= height_reg40;

                                                                        height_reg42 <= height_reg41;

                                                                        height_reg43 <= height_reg42;

                                                                        height_reg44 <= height_reg43;

                                                                        height_reg45 <= height_reg44;

                                                                        height_reg46 <= height_reg45;

                                                                        height_reg47 <= height_reg46;

                                                                        height_reg48 <= height_reg47;

                                                                        height_reg49 <= height_reg48;

                                                                        height_reg50 <= height_reg49;

                                                                        height_reg51 <= height_reg50;

                                                                        height_reg52 <= height_reg51;

                                                                        height_reg53 <= height_reg52;

                                                                        height_reg54 <= height_reg53;

                                                                        height_reg55 <= height_reg54;

                                                                        height_reg56 <= height_reg55;

                                                                        height_reg57 <= height_reg56;

                                                                        height_reg58 <= height_reg57;

                                                                        height_reg59 <= height_reg58;

                                                                        height_reg60 <= height_reg59;

                                                                        height_reg61 <= height_reg60;

                                                                        height_reg62 <= height_reg61;

                                                                        height_reg63 <= height_reg62;

                                                                        height_reg64 <= height_reg63;

                                                                        height_reg65 <= height_reg64;

                                                                        height_reg66 <= height_reg65;

                                                                        height_reg67 <= height_reg66;

                                                                        height_reg68 <= height_reg67;

                                                                        height_reg69 <= height_reg68;

                                                                        height_reg70 <= height_reg69;

                                                                        height_reg71 <= height_reg70;

                                                                        height_reg72 <= height_reg71;

                                                                        height_reg73 <= height_reg72;

                                                                        height_reg74 <= height_reg73;

                                                                        height_reg75 <= height_reg74;

                                                                        height_reg76 <= height_reg75;

                                                                        height_reg77 <= height_reg76;

                                                                        height_reg78 <= height_reg77;

                                                                        height_reg79 <= height_reg78;

                                                                        height_reg80 <= height_reg79;

                                                                        height_reg81 <= height_reg80;

                                                                        height_reg82 <= height_reg81;

                                                                        height_reg83 <= height_reg82;

                                                                        height_reg84 <= height_reg83;

                                                                        height_reg85 <= height_reg84;

                                                                        height_reg86 <= height_reg85;

                                                                        height_reg87 <= height_reg86;

                                                                        height_reg88 <= height_reg87;

                                                                        height_reg89 <= height_reg88;

                                                                        height_reg90 <= height_reg89;

                                                                        height_reg91 <= height_reg90;

                                                                        height_reg92 <= height_reg91;

                                                                        height_reg93 <= height_reg92;

                                                                        height_reg94 <= height_reg93;

                                                                        height_reg95 <= height_reg94;

                                                                        height_reg96 <= height_reg95;

                                                                        height_reg97 <= height_reg96;

                                                                        height_reg98 <= height_reg97;

                                                                        height_reg99 <= height_reg98;                                                  

                                                                        draw_state<=color; 

                                                end

                                               

                                                color: begin

                                                 

                                                                        if((c0|c1|c2|c3|c4|c5|c6|c7|c8|c9|c10|c11|c12|c13|c14|c15|c16|c17|c18|c19|c20|c21|c22|c23|c24|c25|c26|c27|c28|c29|c30|c31|c32|c33|c34|c35|c36|c37|c38|c39|c40|c41|c42|c43|c44|c45|c46|c47|c48|c49|c50|c51|c52|c53|c54|c55|c56|c57|c58|c59|c60|c61|c62|c63|c64|c65|c66|c67|c68|c69|c70|c71|c72|c73|c74|c75|c76|c77|c78|c79|c80|c81|c82|c83|c84|c85|c86|c87|c88|c89|c90|c91|c92|c93|c94|c95|c96|c97|c98|c99) & ~(iY%10 ==0) | eye1 | eye2) begin

                                                                                                if (sigSel[4:2]==3'd0) begin

                                                                                                                        reg_R<=red;//10'h0;

                                                                                                                        reg_G<=green;//10'h0;

                                                                                                                        reg_B<=blue;//10'hfff;

                                                                                                end else if (sigSel[4:2]==3'd1) begin

                                                                                                                        reg_R <= sampleAudio[14:5];

                                                                                                                        reg_G <= ~sampleAudio[12:3];

                                                                                                                        reg_B <= sampleAudio[9:0];

                                                                                                end else if (sigSel[4:2]==3'd2) begin

                                                                                                                        reg_R <= sampleBass[14:5];

                                                                                                                        reg_G <= ~sampleBass[12:3];

                                                                                                                        reg_B <= sampleBass[9:0];

                                                                                                end else if (sigSel[4:2]==3'd3) begin

                                                                                                                        reg_R <= sampleCymbal[14:5];

                                                                                                                        reg_G <= ~sampleCymbal[12:3];

                                                                                                                        reg_B <= sampleCymbal[9:0];

                                                                                                end else if (sigSel[4:2]==3'd4) begin

                                                                                                                        reg_R <= sampleVoice[14:5];

                                                                                                                        reg_G <= ~sampleVoice[12:3];

                                                                                                                        reg_B <= sampleVoice[9:0];

                                                                                                end else begin

                                                                                                                        reg_R<=red;//10'h0;

                                                                                                                        reg_G<=green;//10'h0;

                                                                                                                        reg_B<=blue;//10'hfff;

                                                                                                end

                                                                                                if(eye1) begin

                                                                                                                        if (sigSel[4:2]==3'd0)begin

                                                                                                                                                reg_R<=red;

                                                                                                                                                reg_G<=green;

                                                                                                                                                reg_B<=~blue;

                                                                                                                        end else if (sigSel[4:2]==3'd5) begin

                                                                                                                                                reg_R<=~sampleBass[14:5];

                                                                                                                                                reg_G<=~sampleCymbal[14:5];

                                                                                                                                                reg_B<=~sampleVoice[14:5];

                                                                                                                        end else if (sigSel[4:2]==3'd6) begin

                                                                                                                                                reg_R<=~sampleCymbal[14:5];

                                                                                                                                                reg_G<=~sampleVoice[14:5];

                                                                                                                                                reg_B<=~sampleBass[14:5];

                                                                                                                        end else if (sigSel[4:2]==3'd7) begin

                                                                                                                                                reg_R<=~sampleVoice[14:5];

                                                                                                                                                reg_G<=~sampleBass[14:5];

                                                                                                                                                reg_B<=~sampleCymbal[14:5];

                                                                                                                        end

                                                                                                end                                                                                       

                                                                                                if(eye2) begin

                                                                                                                        if (sigSel[4:2]==3'd0)begin

                                                                                                                                                reg_R<=red;

                                                                                                                                                reg_G<=~green;

                                                                                                                                                reg_B<=blue;

                                                                                                                        end else if (sigSel[4:2]==3'd5) begin

                                                                                                                                                reg_R<=~bass[14:5];

                                                                                                                                                reg_G<=~cymbal[14:5];

                                                                                                                                                reg_B<=~voice[14:5];

                                                                                                                        end else if (sigSel[4:2]==3'd6) begin

                                                                                                                                                reg_R<=~cymbal[14:5];

                                                                                                                                                reg_G<=~voice[14:5];

                                                                                                                                                reg_B<=~bass[14:5];

                                                                                                                        end else if (sigSel[4:2]==3'd7) begin

                                                                                                                                                reg_R<=~voice[14:5];

                                                                                                                                                reg_G<=~bass[14:5];

                                                                                                                                                reg_B<=~cymbal[14:5];

                                                                                                                        end

                                                                                                end                                                                                       

                                                                        end else begin // if not conditions are met

                                                                                                reg_R<=10'h0;

                                                                                                reg_G<=10'h0;

                                                                                                reg_B<=10'h0;

                                                                        end

                                                                       

                                                                        if(vs_sig) //finished drawing

                                                                                                                        draw_state<=init;

                                                end

                                                                       

                                                endcase

                        end //VGA sync

end //always

 

assign state=draw_state;

 

reg vs_state;

reg vs_sig;

 

always @ (posedge CLK) begin //generate a one cycle pulse on each v sync,signals a fully drawn screen

                        if(RST) begin

                                                vs_state<=0;

                        end

                        else begin

                                                case(vs_state)

                                                                        0: begin

                                                                                                vs_sig<=0;

                                                                                                if(~iVGA_VS) begin

                                                                                                                        vs_sig<=1;

                                                                                                                        vs_state<=1;

                                                                                                end

                                                                        end

                                               

                                                                        1: begin

                                                                                                vs_sig<=0;

                                                                                                if(iVGA_VS)

                                                                                                                        vs_state<=0;

                                                                        end

                                                endcase

                        end

end

 

assign oR= reg_R;

assign oG= reg_G;

assign oB= reg_B;

 

 

endmodule

///////////////////////////////////////////////////////////////////

//////////////absolute values//////////////////////////////////////

///////////////////////////////////////////////////////////////////

module abs(out, in, dk_const, clk);

 

                        output reg signed [15:0] out ;

                        input wire signed [15:0] in ;

                        input wire [3:0] dk_const ;

                        input wire clk;

                       

                        wire signed  [17:0] new_out ;

                        //take absolute value and reduce amplitude

                        assign new_out = (in[15]?-in:in)>>dk_const;//out - (out>>>dk_const) + ((in[15]?-in:in)>>>dk_const) ;

                        always @(posedge clk)

                        begin

                                                 out <= new_out ;

                        end

endmodule

///////////////////////////////////////////////////////////////////

//////////// highest order bit find ///////////////////////////////

///////////////////////////////////////////////////////////////////

module firstHbit(in,out,CLK);

input CLK;

input [9:0] in;

output [9:0] out;

 

reg [9:0] out_reg;

always @ (posedge CLK) begin

 

                        if(in[9])

                         out_reg<=10'd479;

                        else if(in[8])

                         out_reg<=10'd360;

                        else if(in[7])

                         out_reg<=10'd320;

                        else if(in[6])

                         out_reg<=10'd280;

                         else if(in[5])

                         out_reg<=10'd240;

                         else if(in[4])

                         out_reg<=10'd200;

                         else if(in[3])

                         out_reg<=10'd160;

                        else if(in[2])

                         out_reg<=10'd120;

                         else if(in[1])

                         out_reg<=10'd80;

                         else if(in[0])

                         out_reg<=10'd40;

                         else

                                                out_reg<=10'd0;

 

end //always

 

assign out=out_reg;

                       

 

endmodule

 

 

 

///////////////////////////////////////////////////////////////////

//// signed mult of 2.16 format 2'comp ////////////////////////////

///////////////////////////////////////////////////////////////////

module signed_mult (out, a, b);

 

                        output                                [17:0]          out;

                        input            signed         [17:0]          a;

                        input            signed         [17:0]          b;

                       

                        wire             signed         [17:0]          out;

                        wire             signed         [35:0]          mult_out;

 

                        assign mult_out = a * b;

                        //assign out = mult_out[33:17];

                        assign out = {mult_out[35], mult_out[32:16]};

endmodule

///////////////////////////////////////////////////////////////////

/// Fourth order IIR filter ///////////////////////////////////////

///////////////////////////////////////////////////////////////////

module IIR4_18bit_fixed (audio_out, audio_in,

                                                                        scale,

                                                                        b1, b2, b3, b4, b5,

                                                                        a2, a3, a4, a5,

                                                                        state_clk, lr_clk, reset) ;

// The filter is a "Direct Form II Transposed"

//

//    a(1)*y(n) = b(1)*x(n) + b(2)*x(n-1) + ... + b(nb+1)*x(n-nb)

//                          - a(2)*y(n-1) - ... - a(na+1)*y(n-na)

//

//    If a(1) is not equal to 1, FILTER normalizes the filter

//    coefficients by a(1).

//

// one audio sample, 16 bit, 2's complement

output reg signed [15:0] audio_out ;

// one audio sample, 16 bit, 2's complement

input wire signed [15:0] audio_in ;

// shift factor for output

input wire [2:0] scale ;

// filter coefficients

input wire signed [17:0] b1, b2, b3, b4, b5, a2, a3, a4, a5 ;

input wire state_clk, lr_clk, reset ;

 

/// filter vars //////////////////////////////////////////////////

wire signed [17:0] f1_mac_new, f1_coeff_x_value ;

reg signed [17:0] f1_coeff, f1_mac_old, f1_value ;

 

// input to filter

reg signed [17:0] x_n ;

// input history x(n-1), x(n-2)

reg signed [17:0] x_n1, x_n2, x_n3, x_n4 ;

 

// output history: y_n is the new filter output, BUT it is

// immediately stored in f1_y_n1 for the next loop through

// the filter state machine

reg signed [17:0] f1_y_n1, f1_y_n2, f1_y_n3, f1_y_n4 ;

 

// MAC operation

signed_mult f1_c_x_v (f1_coeff_x_value, f1_coeff, f1_value);

assign f1_mac_new = f1_mac_old + f1_coeff_x_value ;

 

// state variable

reg [3:0] state ;

//oneshot gen to sync to audio clock

reg last_clk ;

///////////////////////////////////////////////////////////////////

 

//Run the filter state machine FAST so that it completes in one

//audio cycle

always @ (posedge state_clk)

begin

                        if (reset)

                        begin

                                                state <= 4'd15 ; //turn off the state machine                   

                        end

                       

                        else begin

                                                case (state)

                       

                                                                        1:

                                                                        begin

                                                                                                // set up b1*x(n)

                                                                                                f1_mac_old <= 18'd0 ;

                                                                                                f1_coeff <= b1 ;

                                                                                                f1_value <= {audio_in, 2'b0} ;                                                                              

                                                                                                //register input

                                                                                                x_n <= {audio_in, 2'b0} ;                                                                                         

                                                                                                // next state

                                                                                                state <= 4'd2;

                                                                        end

                       

                                                                        2:

                                                                        begin

                                                                                                // set up b2*x(n-1)

                                                                                                f1_mac_old <= f1_mac_new ;

                                                                                                f1_coeff <= b2 ;

                                                                                                f1_value <= x_n1 ;                                                                               

                                                                                                // next state

                                                                                                state <= 4'd3;

                                                                        end

                                                                       

                                                                        3:

                                                                        begin

                                                                                                // set up b3*x(n-2)

                                                                                                f1_mac_old <= f1_mac_new ;

                                                                                                f1_coeff <= b3 ;

                                                                                                f1_value <= x_n2 ;

                                                                                                // next state

                                                                                                state <= 4'd4;

                                                                        end

                                                                       

                                                                        4:

                                                                        begin

                                                                                                // set up b4*x(n-3)

                                                                                                f1_mac_old <= f1_mac_new ;

                                                                                                f1_coeff <= b4 ;

                                                                                                f1_value <= x_n3 ;

                                                                                                // next state

                                                                                                state <= 4'd5;

                                                                        end

                                                                       

                                                                        5:

                                                                        begin

                                                                                                // set up b5*x(n-4)

                                                                                                f1_mac_old <= f1_mac_new ;

                                                                                                f1_coeff <= b5 ;

                                                                                                f1_value <= x_n4 ;

                                                                                                // next state

                                                                                                state <= 4'd6;

                                                                        end

                                                                                                                                               

                                                                        6:

                                                                        begin

                                                                                                // set up -a2*y(n-1)

                                                                                                f1_mac_old <= f1_mac_new ;

                                                                                                f1_coeff <= a2 ;

                                                                                                f1_value <= f1_y_n1 ;

                                                                                                //next state

                                                                                                state <= 4'd7;

                                                                        end

                                                                       

                                                                        7:

                                                                        begin

                                                                                                // set up -a3*y(n-2)

                                                                                                f1_mac_old <= f1_mac_new ;

                                                                                                f1_coeff <= a3 ;

                                                                                                f1_value <= f1_y_n2 ;                                                                                                

                                                                                                //next state

                                                                                                state <= 4'd8;

                                                                        end

                                                                       

                                                                        8:

                                                                        begin

                                                                                                // set up -a4*y(n-3)

                                                                                                f1_mac_old <= f1_mac_new ;

                                                                                                f1_coeff <= a4 ;

                                                                                                f1_value <= f1_y_n3 ;                                                                                                

                                                                                                //next state

                                                                                                state <= 4'd9;

                                                                        end

                                                                       

                                                                        9:

                                                                        begin

                                                                                                // set up -a5*y(n-4)

                                                                                                f1_mac_old <= f1_mac_new ;

                                                                                                f1_coeff <= a5 ;

                                                                                                f1_value <= f1_y_n4 ;                                                                                                

                                                                                                //next state

                                                                                                state <= 4'd10;

                                                                        end

                                                                       

                                                                        10:

                                                                        begin

                                                                                                // get the output

                                                                                                // and put it in the LAST output var

                                                                                                // for the next pass thru the state machine

                                                                                                //mult by four because of coeff scaling

                                                                                                // to prevent overflow

                                                                                                f1_y_n1 <= f1_mac_new<<scale ;

                                                                                                audio_out <= f1_y_n1[17:2] ;                                                                              

                                                                                                // update output history

                                                                                                f1_y_n2 <= f1_y_n1 ;

                                                                                                f1_y_n3 <= f1_y_n2 ;

                                                                                                f1_y_n4 <= f1_y_n3 ;                                                                          

                                                                                                // update input history

                                                                                                x_n1 <= x_n ;

                                                                                                x_n2 <= x_n1 ;

                                                                                                x_n3 <= x_n2 ;

                                                                                                x_n4 <= x_n3 ;

                                                                                                //next state

                                                                                                state <= 4'd15;

                                                                        end

                                                                       

                                                                        15:

                                                                        begin

                                                                                                // wait for the audio clock and one-shot it

                                                                                                if (lr_clk && last_clk==1)

                                                                                                begin

                                                                                                                        state <= 4'd1 ;

                                                                                                                        last_clk <= 1'h0 ;

                                                                                                end

                                                                                                // reset the one-shot memory

                                                                                                else if (~lr_clk && last_clk==0)

                                                                                                begin

                                                                                                                        last_clk <= 1'h1 ;                                                                                 

                                                                                                end               

                                                                        end

                                                                       

                                                                        default:

                                                                        begin

                                                                                                // default state is end state

                                                                                                state <= 4'd15 ;

                                                                        end

                                                endcase

                        end

end               

 

endmodule

 

///////////////////////////////////////////////////////////////////

//// signed mult of 3.24 format 2'comp/////////////////////////////

///////////////////////////////////////////////////////////////////

module signed_mult27 (out, a, b);

                        output                                [26:0]          out;

                        input            signed         [26:0]          a;

                        input            signed         [26:0]          b;

                        wire             signed         [26:0]          out;

                        wire             signed         [53:0]          mult_out;

                        assign mult_out = a * b;

                        assign out = {mult_out[53], mult_out[50:24]};

endmodule

///////////////////////////////////////////////////////////////////

/// Fourth order IIR filter ///////////////////////////////////////

///////////////////////////////////////////////////////////////////

module IIR4_27bit (audio_out, audio_in,

                                                                        scale,

                                                                        b1, b2, b3, b4, b5,

                                                                        a2, a3, a4, a5,

                                                                        state_clk, lr_clk, reset) ;

// The filter is a "Direct Form II Transposed"

//

//    a(1)*y(n) = b(1)*x(n) + b(2)*x(n-1) + ... + b(nb+1)*x(n-nb)

//                          - a(2)*y(n-1) - ... - a(na+1)*y(n-na)

//

//    If a(1) is not equal to 1, FILTER normalizes the filter

//    coefficients by a(1).

//

// one audio sample, 16 bit, 2's complement

output reg signed [15:0] audio_out ;

// one audio sample, 16 bit, 2's complement

input wire signed [15:0] audio_in ;

// shift factor for output

input wire [2:0] scale ;

// filter coefficients

input wire signed [26:0] b1, b2, b3, b4, b5, a2, a3, a4, a5 ;

input wire state_clk, lr_clk, reset ;

 

/// filter vars //////////////////////////////////////////////////

wire signed [26:0] f1_mac_new, f1_coeff_x_value ;

reg signed [26:0] f1_coeff, f1_mac_old, f1_value ;

 

// input to filter

reg signed [26:0] x_n ;

// input history x(n-1), x(n-2)

reg signed [26:0] x_n1, x_n2, x_n3, x_n4 ;

 

// output history: y_n is the new filter output, BUT it is

// immediately stored in f1_y_n1 for the next loop through

// the filter state machine

reg signed [26:0] f1_y_n1, f1_y_n2, f1_y_n3, f1_y_n4 ;

 

// MAC operation

signed_mult27 f1_c_x_v (f1_coeff_x_value, f1_coeff, f1_value);

assign f1_mac_new = f1_mac_old + f1_coeff_x_value ;

 

// state variable

reg [3:0] state ;

//oneshot gen to sync to audio clock

reg last_clk ;

///////////////////////////////////////////////////////////////////

 

//Run the filter state machine FAST so that it completes in one

//audio cycle

always @ (posedge state_clk)

begin

                        if (reset)

                        begin

                                                state <= 4'd15 ; //turn off the state machine                   

                        end

                       

                        else begin

                                                case (state)

                       

                                                                        1:

                                                                        begin

                                                                                                // set up b1*x(n)

                                                                                                f1_mac_old <= 27'd0 ;

                                                                                                f1_coeff <= b1 ;

                                                                                                f1_value <= {audio_in, 11'b0} ;                                                                           

                                                                                                //register input

                                                                                                x_n <= {audio_in, 11'b0} ;                                                                                      

                                                                                                // next state

                                                                                                state <= 4'd2;

                                                                        end

                       

                                                                        2:

                                                                        begin

                                                                                                // set up b2*x(n-1)

                                                                                                f1_mac_old <= f1_mac_new ;

                                                                                                f1_coeff <= b2 ;

                                                                                                f1_value <= x_n1 ;                                                                               

                                                                                                // next state

                                                                                                state <= 4'd3;

                                                                        end

                                                                       

                                                                        3:

                                                                        begin

                                                                                                // set up b3*x(n-2)

                                                                                                f1_mac_old <= f1_mac_new ;

                                                                                                f1_coeff <= b3 ;

                                                                                                f1_value <= x_n2 ;

                                                                                                // next state

                                                                                                state <= 4'd4;

                                                                        end

                                                                       

                                                                        4:

                                                                        begin

                                                                                                // set up b4*x(n-3)

                                                                                                f1_mac_old <= f1_mac_new ;

                                                                                                f1_coeff <= b4 ;

                                                                                                f1_value <= x_n3 ;

                                                                                                // next state

                                                                                                state <= 4'd5;

                                                                        end

                                                                       

                                                                        5:

                                                                        begin

                                                                                                // set up b5*x(n-4)

                                                                                                f1_mac_old <= f1_mac_new ;

                                                                                                f1_coeff <= b5 ;

                                                                                                f1_value <= x_n4 ;

                                                                                                // next state

                                                                                                state <= 4'd6;

                                                                        end

                                                                                                                                               

                                                                        6:

                                                                        begin

                                                                                                // set up -a2*y(n-1)

                                                                                                f1_mac_old <= f1_mac_new ;

                                                                                                f1_coeff <= a2 ;

                                                                                                f1_value <= f1_y_n1 ;

                                                                                                //next state

                                                                                                state <= 4'd7;

                                                                        end

                                                                       

                                                                        7:

                                                                        begin

                                                                                                // set up -a3*y(n-2)

                                                                                                f1_mac_old <= f1_mac_new ;

                                                                                                f1_coeff <= a3 ;

                                                                                                f1_value <= f1_y_n2 ;                                                                                                

                                                                                                //next state

                                                                                                state <= 4'd8;

                                                                        end

                                                                       

                                                                        8:

                                                                        begin

                                                                                                // set up -a4*y(n-3)

                                                                                                f1_mac_old <= f1_mac_new ;

                                                                                                f1_coeff <= a4 ;

                                                                                                f1_value <= f1_y_n3 ;                                                                                                

                                                                                                //next state

                                                                                                state <= 4'd9;

                                                                        end

                                                                       

                                                                        9:

                                                                        begin

                                                                                                // set up -a5*y(n-4)

                                                                                                f1_mac_old <= f1_mac_new ;

                                                                                                f1_coeff <= a5 ;

                                                                                                f1_value <= f1_y_n4 ;                                                                                                

                                                                                                //next state

                                                                                                state <= 4'd10;

                                                                        end

                                                                       

                                                                        10:

                                                                        begin

                                                                                                // get the output

                                                                                                // and put it in the LAST output var

                                                                                                // for the next pass thru the state machine

                                                                                                //mult by four because of coeff scaling

                                                                                                // to prevent overflow

                                                                                                f1_y_n1 <= f1_mac_new<<scale ;

                                                                                                audio_out <= f1_y_n1[26:11] ;                                                                           

                                                                                                // update output history

                                                                                                f1_y_n2 <= f1_y_n1 ;

                                                                                                f1_y_n3 <= f1_y_n2 ;

                                                                                                f1_y_n4 <= f1_y_n3 ;                                                                          

                                                                                                // update input history

                                                                                                x_n1 <= x_n ;

                                                                                                x_n2 <= x_n1 ;

                                                                                                x_n3 <= x_n2 ;

                                                                                                x_n4 <= x_n3 ;

                                                                                                //next state

                                                                                                state <= 4'd15;

                                                                        end

                                                                       

                                                                        15:

                                                                        begin

                                                                                                // wait for the audio clock and one-shot it

                                                                                                if (lr_clk && last_clk==1)

                                                                                                begin

                                                                                                                        state <= 4'd1 ;

                                                                                                                        last_clk <= 1'h0 ;

                                                                                                end

                                                                                                // reset the one-shot memory

                                                                                                else if (~lr_clk && last_clk==0)

                                                                                                begin

                                                                                                                        last_clk <= 1'h1 ;                                                                                 

                                                                                                end               

                                                                        end

                                                                       

                                                                        default:

                                                                        begin

                                                                                                // default state is end state

                                                                                                state <= 4'd15 ;

                                                                        end

                                                endcase

                        end

end               

 

endmodule

///////////////////////////////////////////////////////////////////

///////////////////// Pixel Value Controller //////////////////////

///////////////////////////////////////////////////////////////////

module pixelController(reset, schemeReset, CLK, CLK27, AUDCLK, VGA_VS, VGA_HS, audIn, periodIn, red, green, blue);

//inputs

input reset, VGA_VS, VGA_HS, CLK, CLK27, AUDCLK;

input [7:0] schemeReset;

input signed [15:0] audIn;

input [31:0] periodIn;

//registers

reg [1:0] wtPrd;

reg [31:0] realPeriod;

reg [7:0] schemeCycle;

reg [31:0] schemeCount;

//outputs

output [9:0] red, green, blue;

//output [31:0] periodOut;

//wires

wire [9:0] redValue, greenValue, blueValue;

//wire [31:0] period;

 

//waveform period calculator

//periodCalc calcUnit1(CLK, CLK27, AUDCLK, clk1000, audIn, period);

//pixel variation unit

pixelVar unit1(reset, VGA_VS, CLK, schemeCycle, wtPrd, realPeriod, redValue, greenValue, blueValue);

 

//scheme logic

always @ (posedge CLK) begin

                        if (reset) begin

                                                schemeCount <= 32'd0;

                                                schemeCycle <= schemeReset;

                        end else begin

                                                // scheme cycler

                                                schemeCount <= schemeCount + 32'd1;

                                                if(schemeCount > (periodIn<<4)) begin//32'd90000000)begin

                                                                        schemeCount <= 32'd0;

                                                                        //schemeSubCount <= schemeSubCount + 20'd1;

                                                                        schemeCycle <= schemeCycle + 8'd1;

                                                                        if (schemeCycle > 8'd254) begin//(schemeCycle > 8'd255) begin

                                                                                                schemeCycle <= 8'd0;

                                                                                                wtPrd <= wtPrd + 2'd1;

                                                                                                if (wtPrd == 2'd3) begin

                                                                                                                        wtPrd <= 2'd0;

                                                                                                                        schemeCycle <= schemeCycle + 8'd1;

                                                                                                end

                                                                        end

                                                end

                        end

                        realPeriod <= (periodIn>>5);

end

 

//assign outputs

assign red = redValue;

assign green = greenValue;

assign blue = blueValue;

//assign periodOut = period;

 

endmodule

///////////////////////////////////////////////////////////////////

///////////// CIC N=2 M=1 filter //////////////////////////////////

///////////////////////////////////////////////////////////////////

module CIC_N2_M1_16bit_fixed (audio_out, rf_in,

                                                                        rf_clk, lr_clk, reset) ;

// The filter is a

// double integrator/comb CIC filter

//

// one audio sample, 16 bit, 2's complement

output reg signed [15:0] audio_out ;

input signed [15:0] rf_in ;

input wire rf_clk, lr_clk, reset ;

 

reg signed [39:0] integrator1, comb1 ; //[39:0]

reg signed [39:0] integrator2, comb2, temp_int2 ;

wire signed [39:0] running_sum1, running_sum2  ;

 

always @(posedge rf_clk)

begin

                        if (reset)

                        begin

                                                integrator1 <= 40'd0 ;

                                                integrator2 <= 40'd0 ;

                        end

                        else

                        begin

                                                integrator1 <= integrator1 + { {24{rf_in[15]}}, rf_in} ;

                                                integrator2 <= integrator2 + integrator1 ;

                        end

end

 

always @(posedge lr_clk)

begin

                        temp_int2 <= integrator2 ;

                        comb1 <=  temp_int2 ;

                        comb2 <= running_sum1 ;

                        audio_out <= running_sum2[35:20];

end

 

assign running_sum1 = temp_int2 - comb1 ;

assign running_sum2 = running_sum1 - comb2 ;

 

endmodule

///////////////////////////////////////////////////////////////////

////////////////////// Pixel Color Variation Unit /////////////////

///////////////////////////////////////////////////////////////////

module pixelVar(reset, VGA_VS, CLK, scheme, wtPer, period, red, green, blue);

//inputs

input CLK, reset, VGA_VS;

input [1:0] wtPer;

input [8:0] scheme;

input [31:0] period;

//registers

reg reverse; // reverse the order in which operation is done

reg stat; //stationay second color

reg alt; //second color alternates

reg sync; //synchronize with VGA_VS or not

reg [1:0] thirdVal;

reg [2:0] mode;

reg [2:0] maxCount;

reg [15:0] counter;

reg [31:0] countMax;

reg [9:0] redVal, blueVal, greenVal;

//outputs

output [9:0] red, green, blue;

 

always @ (posedge CLK) begin 

                        sync <= scheme[8];

                        if (reset) begin//if system is reset                                          

                                                redVal <= 10'd0;

                                                greenVal <= 10'd0;

                                                blueVal <= 10'd0;

                                                counter <= 16'd0;

                        end else if (~VGA_VS) begin                                

                                                mode <= scheme[7:5];

                                                reverse <= scheme[4];

                                                thirdVal <= scheme[3:2];

                                                stat <= scheme[1];

                                                alt <= scheme[0];

                                                counter <= counter + 16'd1;//increment count                                   

                                                //set count max - different wait periods to cycle colors

                                                case(wtPer)

                                                                        2'd0: countMax <= period<<3; // 8x bass beat (2x whole note)

                                                                        2'd1: countMax <= period<<2; // 4x bass beat (whole note)

                                                                        2'd2: countMax <= period<<1; // 2x bass beat (half note)

                                                                        2'd3: countMax <= period;//bass beat (quarter note)

                                                endcase

                                                //select color shifting mode

                                                case(mode)

                                                                        3'd0: begin // red up, green down (reverse is direction switch)

                                                                                                //different wait period to cycle colors

                                                                                                if (counter > countMax) begin

                                                                                                                        maxCount <= maxCount + 3'd1;

                                                                                                                        counter <= 16'd0;

                                                                                                                        //red value

                                                                                                                        if(reverse) begin

                                                                                                                                                if (redVal < 10'd1020) begin

                                                                                                                                                                        redVal <= redVal + 10'd10;

                                                                                                                                                end else begin

                                                                                                                                                                        redVal <= 10'd0;

                                                                                                                                                end                                                               

                                                                                                                        end else begin

                                                                                                                                                if (redVal > 10'd0) begin

                                                                                                                                                                        redVal <= redVal - 10'd10;

                                                                                                                                                end else begin

                                                                                                                                                                        redVal <= 10'd1020;

                                                                                                                                                end

                                                                                                                        end

                                                                                                                        //green value                

                                                                                                                        if (~stat) begin //stationary second color

                                                                                                                                                if (reverse) begin

                                                                                                                                                                        if (greenVal > 10'd0) begin

                                                                                                                                                                                                greenVal <= greenVal - 10'd10;

                                                                                                                                                                        end else begin

                                                                                                                                                                                                greenVal <= 10'd1020;

                                                                                                                                                                        end

                                                                                                                                                end else begin

                                                                                                                                                                        if (greenVal < 10'd1020) begin

                                                                                                                                                                                                greenVal <= greenVal + 10'd10;

                                                                                                                                                                        end else begin

                                                                                                                                                                                                greenVal <= 10'd0;

                                                                                                                                                                        end

                                                                                                                                                end

                                                                                                                                                if (alt && maxCount>3) begin //alternate third color

                                                                                                                                                                        maxCount <= 3'd0;

                                                                                                                                                                        if (blueVal==10'd1000) begin //reset third color at 1000

                                                                                                                                                                                                blueVal <= 10'd0;

                                                                                                                                                                        end else begin

                                                                                                                                                                                                blueVal <= blueVal + 10'd200;

                                                                                                                                                                        end

                                                                                                                                                end else begin//set third color to constant value                                                                                                                                                        

                                                                                                                                                                        case(thirdVal)

                                                                                                                                                                                                2'd0: blueVal <= 10'd0;

                                                                                                                                                                                                2'd1: blueVal <= 10'd250;

                                                                                                                                                                                                2'd2: blueVal <= 10'd500;

                                                                                                                                                                                                2'd3: blueVal <= 10'd750;

                                                                                                                                                                        endcase

                                                                                                                                                end

                                                                                                                        end else begin                                                                                                                                       

                                                                                                                                                if (alt && maxCount>3) begin //alternate second color

                                                                                                                                                                        maxCount <= 3'd0;

                                                                                                                                                                        if (greenVal==10'd1000) begin //reset second color at 1000

                                                                                                                                                                                                greenVal <= 10'd0;

                                                                                                                                                                        end else begin

                                                                                                                                                                                                greenVal <= greenVal + 10'd200;

                                                                                                                                                                        end

                                                                                                                                                end

                                                                                                                        end //stat check

                                                                                                end //end count check

                                                                        end //end of this case

                                                                       

                                                                        3'd1: begin //blue up, red down (reverse is direction switch)                                                                           

                                                                                                //different wait period to cycle colors

                                                                                                if (counter > countMax) begin

                                                                                                                        maxCount <= maxCount + 3'd1;

                                                                                                                        counter <= 16'd0;

                                                                                                                        //red value

                                                                                                                        if(reverse) begin

                                                                                                                                                if (blueVal < 10'd1020) begin

                                                                                                                                                                        blueVal <= blueVal + 10'd10;

                                                                                                                                                end else begin

                                                                                                                                                                        blueVal <= 10'd0;

                                                                                                                                                end                                                               

                                                                                                                        end else begin

                                                                                                                                                if (blueVal > 10'd0) begin

                                                                                                                                                                        blueVal <= blueVal - 10'd10;

                                                                                                                                                end else begin

                                                                                                                                                                        blueVal <= 10'd1020;

                                                                                                                                                end

                                                                                                                        end

                                                                                                                        //green value                

                                                                                                                        if (~stat) begin //stationary second color

                                                                                                                                                if (reverse) begin

                                                                                                                                                                        if (redVal > 10'd0) begin

                                                                                                                                                                                                redVal <= redVal - 10'd10;

                                                                                                                                                                        end else begin

                                                                                                                                                                                                redVal <= 10'd1020;

                                                                                                                                                                        end

                                                                                                                                                end else begin

                                                                                                                                                                        if (redVal < 10'd1020) begin

                                                                                                                                                                                                redVal <= redVal + 10'd10;

                                                                                                                                                                        end else begin

                                                                                                                                                                                                redVal <= 10'd0;

                                                                                                                                                                        end

                                                                                                                                                end

                                                                                                                                                if (alt && maxCount>3) begin //alternate third color

                                                                                                                                                                        maxCount <= 3'd0;

                                                                                                                                                                        if (greenVal==10'd1000) begin //reset third color at 1000

                                                                                                                                                                                                greenVal <= 10'd0;

                                                                                                                                                                        end else begin

                                                                                                                                                                                                greenVal <= greenVal + 10'd200;

                                                                                                                                                                        end

                                                                                                                                                end else begin//set third color to constant value                                                                                                                                                        

                                                                                                                                                                        case(thirdVal)

                                                                                                                                                                                                2'd0: greenVal <= 10'd0;

                                                                                                                                                                                                2'd1: greenVal <= 10'd250;

                                                                                                                                                                                                2'd2: greenVal <= 10'd500;

                                                                                                                                                                                                2'd3: greenVal <= 10'd750;

                                                                                                                                                                        endcase

                                                                                                                                                end

                                                                                                                        end else begin                                                                                                                                       

                                                                                                                                                if (alt && maxCount>3) begin //alternate second color

                                                                                                                                                                        maxCount <= 3'd0;

                                                                                                                                                                        if (redVal==10'd1000) begin //reset second color at 1000

                                                                                                                                                                                                redVal <= 10'd0;

                                                                                                                                                                        end else begin

                                                                                                                                                                                                redVal <= redVal + 10'd200;

                                                                                                                                                                        end

                                                                                                                                                end

                                                                                                                        end //stat check

                                                                                                end //end count check

                                                                        end//end of this case

                                                                       

                                                                        3'd2: begin //green up, blue down (reverse is direction switch)                                                                                              

                                                                                                //different wait period to cycle colors

                                                                                                if (counter > countMax) begin

                                                                                                                        maxCount <= maxCount + 3'd1;

                                                                                                                        counter <= 16'd0;

                                                                                                                        //red value

                                                                                                                        if(reverse) begin

                                                                                                                                                if (greenVal < 10'd1020) begin