How does this direct digital synthesis accumulator work?

So, I grabbed some code online and morphed it to work with my DE2-115 board, and now I need some help understanding exactly how it works.

DDS_accum <= DDS_accum + 32'h16FC7BBC +
((256+((message[15]==0)? message[15:7]+256 : message[15:7]-256))<<15) ; // "audio input"


I need help understand exactly why the above Verilog HDL line exists. The large block of code shown below is to show you where it's implemented.

This is the main block of my Senior Design Project, but, my major at college teaches me about software and hardware, not so much Frequency Modulation. So, a lot of this is going right over my head.

I've read through this and some wikipedia pages and some youtube videos, but, I just don't understand the point of the constant and playing with the message signal in the line above.

//make a direct digital synthesis accumulator
// and output a 10-bit sine wave to the VGA plug
// set carrier frequency to 1 MHz DDS_incr = 32'h51EB84C = 85,899,340
// 11 MHz 32'h3851DCA8 = 944889000
// 9 MHz 2DF8F778 (771291000) : 4.5 16FC7BBC (385,645,500)
// 7 Mhz 274AF224 (659223076)
// set modulation to 400 Hz 85E7

// This outputs at 146.0 MHz.

always @ (posedge CLOCK_50) begin
//generate 4.5 Mhz square wave carrier with FM modulation
// 32'h16FC7BBC = 385645500
DDS_accum <= DDS_accum + 32'h16FC7BBC +
((256+((message[15]==0)? message[15:7]+256 : message[15:7]-256))<<15) ; // "audio input"
end

//hook up the ROM table for carrier
sqwave sqTable(CLOCK_50, DDS_accum[31:24], sq_out);

//use the VGA DAC for an FM modulated RF signal
assign VGA_R = sq_out;
assign VGA_SYNC = 1 ;
assign VGA_BLANK = 1 ;
endmodule

//////////////////////////////////////////////////
// Square wave table for the DDS
input clock;
output [7:0] sq; // changed to 7:0
reg [7:0] sq;    // changed to 7:0
always @ (posedge clock)
begin
sq <= (address<128)? 8'h7f : 8'h01 ; // changed
end
endmodule
///////////////////////////////////////////////////


I apologize for the large block of code, but that's the heart of this FM Transmitter. This code modulates a 24-bit input audio signal from the Line In port and out the VGA_R port as an FM signal at around 146.0 MHz.

• FYI, I originally had VHDL as a tag because the rest of my code is in VHDL, and I took a course on VHDL, and I'm just learning Verilog on my own. Apr 21, 2014 at 19:33

Frequency modulation basically means that the frequency of the carrier is changed depending on the magnitude of the message (the audio signal). If the magnitude is positive, the frequency is increased. If the magnitude is negative, the frequency is decreased. Hence 'frequency modulation' because the frequency is being changed instead of the amplitude (AM) or the phase (PM).

In this case, a DDS is being used to generate the carrier wave. Direct digital synthesis basically involves outputting samples of a waveform from a lookup table at a specific rate. The rate is determined by a counter, called the phase accumulator. At every clock cycle, the counter is incremented by a little bit - the 'phase' accumulated by the carrier wave over the clock period. Generally DDS counters have a number of fractional bits so that the counter can accumulate a more accurate phase step on each clock period. It looks like this one does not have any fractional bits, probably because of the modulation and relatively high output frequency. After that, the output of the counter is fed to the lookup table, selecting a sample. A constant phase step will produce a constant frequency. However, adjusting the phase step by adding the message data will vary the frequency in lockstep with the message, forming an FM modulated signal.

This line looks like it is adding the audio message data to the phase step, but with some extra work to rescale it properly and deal with the sign bit.

Edit: Never mind, it does have 24 fractional bits. The lowest 24 bits of the accumulator are not used in the table lookup.

• Thank you for your response!! That helps clear up multiple things =) Only one thing I still don't understand, why do they play with the message signal like that? Why can't I do: DDS_accum <= DDS_accum + 32'h16FC7BBC + message[15:7];? Apr 21, 2014 at 18:56
• As I said, sign bit and rescaling. The highest bit is checked to see if it is set or not to determine if an offset needs to be applied. Also, the whole thing is shifted by 15 bits to set the FM deviation (modulation depth). Without this, the frequency would not vary enough to be receivable. I think the +256 terms are there to make sure the result is positive so that there is no issue with the shift left discarding the sign bit. Apr 21, 2014 at 19:15
• Ahhhhh, thank you alex!!! Now I can actually explain the code =P Apr 21, 2014 at 19:18
• Alex, I apologize for bothering you with another question about this, but, I don't understand how the constant value: 32'h16FC7BBC can output a 104.7 MHz signal when fout = fclk * ( phase_step / N ) is used. Where N = 2^32; phase_step = 32'h16FC7BBC; fclk = 50 MHz; fout = 4.5 MHz. I know the outputted signal is 104.7 MHz because the FM Radio plays the music from the FPGA board. Apr 22, 2014 at 18:29
• That's one thing that I was wondering about as well, actually. It's not possible for a DDS with a sample rate of 50 MHz to output a non-aliased waveform above 25 MHz. However, it looks like what's going on is that it is actually generating a square wave with a lot of odd harmonics. The FPGA output pins tend to have a very fast slew rate, so it would be possible to generate harmonics into the 100s of MHz. 104.7 / 23 is 4.55 MHz. It would be interesting to look at the output on a spectrum analyzer. Apr 23, 2014 at 3:14