# Phase accumulator

Brian

I had a look at some of the Verilog again. For a decimation of 8,
decim_strobe pulses every 64MHz/4 when FR_DECIM_RATE is equal to 3, so
this is correct. hb_strobe will then be 16MHz/2. I’m looking at the
phase_acc and cordic now. When the DDC gets set to -20MHz as is the
case when we’re using a 7901 tvrx, we have the following c++ code to
calculate the value to write to the FPGA:

compute_freq_control_word_fpga (double master_freq, double target_freq,
double *actual_freq, bool verbose)
{
static const int NBITS = 14;

int v = (int) rint (target_freq / master_freq * pow (2.0, 32.0));

if (0)
v = (v >> (32 - NBITS)) << (32 - NBITS); // keep only top NBITS

*actual_freq = v * master_freq / pow (2.0, 32.0);

if (verbose)
fprintf (stderr,
“compute_freq_control_word_fpga: target = %g actual = %g delta
= %g\n”,
target_freq, *actual_freq, *actual_freq - target_freq);

return (unsigned int) v;
}

v then gets written to FR_RX_FREQ_0. This is used for the phase
accumulator. For -20MHz, v = 2952790016. In the phase accumulator,
we have:

always @(posedge clk)
if(reset)
phase <= #1 32’b0;
phase <= #1 serial_data;
else if(enable & strobe)
phase <= #1 phase + freq;

FR_RX_FREQ_0, freq gets the value 2952790016? enable comes from
rx_enable which gets set in master_control. strobe comes from
sample_strobe, which gets set to 1 in master_control. So on the first
clock pulse after writing to FR_RX_FREQ_0, phase will be 2952790016?
This value keeps on getting added to phase on every clock pulse?
Phase is 32 bits, so is the value then truncated? I know that the top
16 bits of phase is used in cordic.v.

So does the following happen: phase gets added each clock pulse, the
overflow is discarded and cordic uses the top 16 bits of phase? At
the next clock pulse, phase changes, so phase[31:16] that enters
cordic is different? Or does phase get a once-off value that is used
in cordic.v? The word ‘accumulator’ gives me the idea that something

Then another question to anyone who has used the cordic testbed. In
cordic_tb.v included with Gnuradio, we have `include “sine.txt”. I’m
assuming that for a 20MHz signal that needs to be mixed down, this
will be a text file with samples of a 20MHz sine wave sampled at
64MHz? So I can just generate it in Octave or Matlab and use it to
run the testbed?

Thank you very much for the help.

Sebastiaan

On Tue, Aug 12, 2008 at 5:13 PM, Sebastiaan H. [email protected]
wrote:

``````                           double *actual_freq, bool verbose)
``````

if (verbose)
fprintf (stderr,
“compute_freq_control_word_fpga: target = %g actual = %g delta = %g\n”,
target_freq, *actual_freq, *actual_freq - target_freq);

return (unsigned int) v;
}

v then gets written to FR_RX_FREQ_0. This is used for the phase
accumulator. For -20MHz, v = 2952790016. In the phase accumulator,
we have:

Not quite - it’s a signed number so it’s really -1342177280.

overflow is discarded and cordic uses the top 16 bits of phase? At
the next clock pulse, phase changes, so phase[31:16] that enters
cordic is different? Or does phase get a once-off value that is used
in cordic.v? The word ‘accumulator’ gives me the idea that something

The first scenario sounds like the correct answer. This is a phase
accumulation that feeds the CORDIC which will then perform the mixing
operation. I think you get it.

Then another question to anyone who has used the cordic testbed. In
cordic_tb.v included with Gnuradio, we have `include “sine.txt”. I’m
assuming that for a 20MHz signal that needs to be mixed down, this
will be a text file with samples of a 20MHz sine wave sampled at
64MHz? So I can just generate it in Octave or Matlab and use it to
run the testbed?

“sine.txt” looks to be a routine that will actually stimulate the
CORDIC. You should probably do something more interesting that just a
20MHz tone. Even a tone at 20.1MHz might be more interesting, so you
get a 100kHz tone out from the mixing process.

You’re going to have to fill in the Verilog that should be in
“sine.txt”. I wrote a math_real.v package that is in the repository
here:

``````http://gnuradio.utah.edu/trac/browser/usrp2/trunk/fpga/models/math_real.v
``````

You can use that to generate sin, cos, etc within Verilog.

Hope this helps.

Brian