 # 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

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.