discuss-gnuradio
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Discuss-gnuradio] Decimation questions


From: Sebastiaan Heunis
Subject: Re: [Discuss-gnuradio] Decimation questions
Date: Tue, 12 Aug 2008 14:03:14 +0200

Brian

Thanks for the help so far.  I've really figured out a lot of the
decimation stuff so far.  I plan on simulating the decimation scheme
in Matlab/C++ to see exactly what happens and where unwanted effects
might be introduced.  I'm supposed to investigate the current scheme
to see if it meets our needs and maybe implement another scheme if
necessary.  This is a part of the master's degree that I am doing.  I
will make the decimation info available to anyone interested in it.

The value FR_RX_PHASE_0 is 0.  When the USRP is initialized,
FR_RX_PHASE_0 - 3 all get the value 0 and I don't see them being set
anywhere else when a normal downconversion is performed.
FR_DECIM_RATE gets set to decim/2 -1 when the FPGA has a halfband
filter in it.  The -1 is probably due to zero indexing as you
mentioned.

FR_RX_FREQ_0 - 3 still confuses me a little.  When a 7901 tv tuner
module is used, the second IF is at 20MHz.  I followed the code in
db_tv_rx.py and usrp.py and saw that in this case we have
set_rx_freq(0,-20e6).  In usrp_standard.cc we have the following code
in set_rx_freq:

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 for channel 0.  I still need to
figure out how this frequency value is used in the FPGA to generate
the sine and cosine waves used in the cordic algorithm since somehow a
20MHz signal is generated from v.  From what I understand, our I and Q
signals are multiplied by a sine and cosine and then passed to the cic
filter.  This leaves only the components centered at 0Hz, since the
cic low pass filters and decimates it.  The hbf also lowpass filters
and decimates by a further factor of 2.

So I understand most of the Python->C++->Verilog code.  It's just the
Verilog itself that I'm still stuck at.  I did some VHDL last year, so
I'm not totally lost.  What I would like to know is the following.  We
have this in the rx_chain part:

phase_acc #(FREQADDR,PHASEADDR,32) rx_phase_acc
     (.clk(clock),.reset(reset),.enable(enable),
      
.serial_addr(serial_addr),.serial_data(serial_data),.serial_strobe(serial_strobe),
      .strobe(sample_strobe),.phase(phase) );

and this in the phase_acc part:

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;

>From the VHDL that I know, my guess is that serial_strobe gets
asserted whenever the FX2 chip writes to the FPGA, serial_addr is an
address that the FX2 sends to the FPGA and serial_data is the value
that gets written to that address.  Is this correct?

So, the setting_reg#... line above drives the freq wire with the value
that the FX2 writes to FREQADDR?  This only happens once when we tune
to the desired frequency, so we just keep adding the same freq value
to phase every 1/64MHz?

When I know the above, I should be fine in figuring the rest out.

Thanks for your help.

Sebastiaan Heunis




reply via email to

[Prev in Thread] Current Thread [Next in Thread]