[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Discuss-gnuradio] Re: Phase accumulator
From: |
Brian Padalino |
Subject: |
[Discuss-gnuradio] Re: Phase accumulator |
Date: |
Tue, 12 Aug 2008 17:31:58 -0400 |
On Tue, Aug 12, 2008 at 5:13 PM, Sebastiaan Heunis <address@hidden> wrote:
> 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:
Not quite - it's a signed number so it's really -1342177280.
> setting_reg #(FREQADDR)
> sr_rxfreq0(.clock(clk),.reset(1'b0),.strobe(serial_strobe),.addr(serial_addr),.in(serial_data),.out(freq));
>
> always @(posedge clk)
> if(reset)
> phase <= #1 32'b0;
> else if(serial_strobe & (serial_addr == PHASEADDR))
> phase <= #1 serial_data;
> else if(enable & strobe)
> phase <= #1 phase + freq;
>
> so when serial_strobe = 1 and serial_addr is the address of
> 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
> keeps on getting added.
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