Create a new VHDL source module called "dac_if". This module takes 16-bit parallel stereo data and converts it to the serial format required by the D/A converter. When L_start is high, a 16-bit left channel data word is loaded into the 16-bit serial shift register SREG on the falling edge of SCLK. When L_start goes low, SCLK shifts the data out of SREG, MSBit first to the serial output SDATA at a rate of 1.56 Mb/s. Simlarly, when R_start goes high, right channel data is loaded into SREG and then shifted out to SDATA. Output data changes on the falling edge of SCLK, so that it is stable when the DAC is reading the data on the rising edge of SCLK.
Create a new VHDL source module called "tone". This module generates a signed triangular wave, at a sampling rate of 48.8 KHz. The frequency of the tone is determined by the input pitch. The process cnt_pr generates an unsigned sawtooth waveform count by incrementing a 16-bit counter pitch values every clock cycle. The frequency with which it traverses the whole 16-bit count range is thus proportional to pitch. The lowest possible tone frequency is obtained when pitch=1. It then takes 65,536 cycles to traverse the range of the counter. The frequency is then 0.745 Hz. If pitch is set to 1000, the frequency would be 745 Hz.
To change the tone wave to a rectangular wave, change the code as shown below.
Create a new VHDL source module called "wail". This module creates an instance of the module tone and then modulates the pitch up and down to produce a “wailing” siren. The inputs hi_pitch and lo_pitch define the upper and lower limits of the generated tone. The inputs wspeed and wclk determine how fast the pitch changes. The wailing tone is generated by the process wp. This process is run on the rising edge of wclk. This is a slow clock (approx. 48 Hz.) Every wclk cycle, the current pitch is raised or lowered depending on the value of updn. When updn=’1’, the pitch rises. When updn=’0’, the pitch lowers. The input wspeed determines how much the pitch changes every wclk cycle. When the current pitch exceeds hi_pitch, updn is set to ‘0’ so that the pitch will start decreasing. Similarly, when the current pitch is lower than lo_pitch, updn is set to ‘1’ to start the tone rising again.
Create a new VHDL source module called "siren". This is the top level that hooks it all together. The constants lo_tone, hi_tone and wail_speed define the parameters of the siren. The 20-bit timing counter tcount is used to generate all the necessary timing signals. The module wail is instanced to generate the 16-bit signed audio sequences data_L and data_R (the same data is sent to both channels). These sequences are then sent to an instance of dac_if to convert them to the required serial stream. Primary outputs of this top level module go directly to the DAC.