ADC questions

Hi

I have a few questions to ask about the ADC if anyone could please
help me? I know that it has a 12-bit output, so our output is between
0 and 4095. I would just like to know how this ADC input gets
converted after leaving the adc_interface block in the FPGA. In other
words, how are positive and negative numbers represented, etc? The
FPGA converts the 12bit input to a 16bit output. What is done to get
it from the 0-4095 input to a 16bit output with + and - numbers?

Thank you very much.

Sebastiaan


Sebastiaan H.
Radar and Remote Sensing Group, University of Cape Town
Tel: +27 83 305 5667

On Tue, Sep 23, 2008 at 11:04 AM, Sebastiaan H. [email protected]
wrote:

Hi

I have a few questions to ask about the ADC if anyone could please
help me? I know that it has a 12-bit output, so our output is between
0 and 4095. I would just like to know how this ADC input gets
converted after leaving the adc_interface block in the FPGA. In other
words, how are positive and negative numbers represented, etc? The
FPGA converts the 12bit input to a 16bit output. What is done to get
it from the 0-4095 input to a 16bit output with + and - numbers?

From the AD9862 datasheet, page 23:

The Rx data output format can be configured for either twos
complement or offset binary. This is controlled by the Rx Twos
Complement register.

So you are getting the twos compliment already from the ADC.

The extra bits comes from decimation and mixing. It is originally
extended in the adc_interface.v here:

http://gnuradio.org/trac/browser/gnuradio/trunk/usrp/fpga/sdr_lib/adc_interface.v#L34

Note the sign bit concatenated with the whole value then zero-extended
by 3 bits of 0’s. The later decimation filtering helps make the zero
extension valid.

Hope this helps.

Brian

Brian

Thanks for the reply. I see from this Verilog line that the adc input
gets sign extended and gets 3 zeros at the back as you mentioned.

rx_dcoffset #(`FR_ADC_OFFSET_0)
rx_dcoffset0(.clock(clock),.enable(dco_en[0]),.reset(reset),.adc_in({adc0[11],adc0,3’b0}),.adc_out(adc0_corr),
.serial_addr(serial_addr),.serial_data(serial_data),.serial_strobe(serial_strobe));

I just don’t know how the rx_dcoffset part works. I don’t know where
in the c++ or Python code the FR_ADC_OFFSET registers get written, so
I can’t follow it that well. Does this remove a DC offset introduced
by the ADC chip?

What I’m busy doing is to test the Verilog code with iverilog. I want
to know how input samples should look that I am using to test the
different FPGA blocks. If I, for instance, generate an FM signal that
I want to send into the cordic block, do I generate a signal and
convert it to 12-bit two’s complement, extend the sign bit and pad it
with 3 zeros at the beginning to get it to 16-bits? Can I then send
this signal to the cordic block and assume that this is what it would
look like in the FPGA?

What does the AGC level sensing part in adc_interface do? Does this
monitor the level of the incoming samples to see if clipping occurs?
The last part, the mux, only routes the different adc inputs to the
correct DDC channels in the FPGA, right?

Thanks in advance.

Sebastiaan


Sebastiaan H.
Radar and Remote Sensing Group, University of Cape Town
Tel: +27 83 305 5667

On Tue, Sep 23, 2008 at 4:08 PM, Sebastiaan H. [email protected]
wrote:

in the c++ or Python code the FR_ADC_OFFSET registers get written, so
I can’t follow it that well. Does this remove a DC offset introduced
by the ADC chip?

The ADC doesn’t introduce any DC offset - the signal on the analog
pins just may have some DC offset. The rx_dcoffset comepnsation
module just does a long running average of the signal and subtracts
out the DC component before shipping the signal off.

What I’m busy doing is to test the Verilog code with iverilog. I want
to know how input samples should look that I am using to test the
different FPGA blocks. If I, for instance, generate an FM signal that
I want to send into the cordic block, do I generate a signal and
convert it to 12-bit two’s complement, extend the sign bit and pad it
with 3 zeros at the beginning to get it to 16-bits? Can I then send
this signal to the cordic block and assume that this is what it would
look like in the FPGA?

Is your FM signal at a carrier or at baseband? If it’s at baseband,
you need to send it in two different ports - one for the I and one for
the Q, and bypass the CORDIC. If it is at some residual carrier and
requires mixing down, then you need to just set it to one input port
and set the CORDIC phase accumulator to be equal to the negative of
the residual carrier to mix the signal back down to baseband.

What does the AGC level sensing part in adc_interface do? Does this
monitor the level of the incoming samples to see if clipping occurs?
The last part, the mux, only routes the different adc inputs to the
correct DDC channels in the FPGA, right?

As for the AGC and mux, I believe you are correct - but I am no
authority on the subject.

Good luck with your simulation.

Brian

Brian

Thanks. I understand the offset part then. Nothing happens if there
is no DC offset. I want to simulate an FM signal coming from the
TVRX, so the TVRX output is 20MHz, I understand that I then need to
write 2952790016 to the FR_RX_FREQ_0 register in the phase_acc. The
cordic will then multiply this input signal by a 20MHz cos and sine to
generate the I and Q channels. I just need to generate an FM signal
and get it to 16-bits as previously described and send it to the
cordic with the phase value written to the freq register?

Sebastiaan


Sebastiaan H.
Radar and Remote Sensing Group, University of Cape Town
Tel: +27 83 305 5667

On Tue, Sep 23, 2008 at 4:54 PM, Sebastiaan H. [email protected]
wrote:

Brian

Thanks. I understand the offset part then. Nothing happens if there
is no DC offset. I want to simulate an FM signal coming from the
TVRX, so the TVRX output is 20MHz, I understand that I then need to
write 2952790016 to the FR_RX_FREQ_0 register in the phase_acc. The
cordic will then multiply this input signal by a 20MHz cos and sine to
generate the I and Q channels. I just need to generate an FM signal
and get it to 16-bits as previously described and send it to the
cordic with the phase value written to the freq register?

Yes.

Brian

Brian

Sorry to bother. I have one more question for now. I wrote a Python
app to generate an input signal, convert it to 12-bit two’s complement
and then bitshift it left by 3 and sign-extend it to get it to the
representation used inside the FPGA. My question now is that if I
feed this input signal into the cordic, I’ll somehow get it back to
decimal in order to plot it in Matlab and see what happened. Do I do
the inverse that I previously did (shift it right by 3 and remove the
sign extension and then take it from two’s complement to decimal?)
Let’s say I take the signal from the cordic and pass it to the CIC
filter. When I want to have a look at the output of the CIC filter,
can I also do the above to get the output to 12-bit decimal?

Thanks in advance.

Sebastiaan


Sebastiaan H.
Radar and Remote Sensing Group, University of Cape Town
Tel: +27 83 305 5667

On Tue, Sep 23, 2008 at 10:08:02PM +0200, Sebastiaan H. wrote:

I just don’t know how the rx_dcoffset part works. I don’t know where
in the c++ or Python code the FR_ADC_OFFSET registers get written, so
I can’t follow it that well. Does this remove a DC offset introduced
by the ADC chip?

We generally don’t use the FR_ADC_OFFSET registers since the real
offset is f(temperature). Instead we compute an approximation to the
DC offset and subtract it from the samples.

Eric

On Tue, Sep 23, 2008 at 05:04:54PM +0200, Sebastiaan H. wrote:

Thank you very much.

Sebastiaan

See especially pages 8 and 9 of

http://gnuradio.org/trac/attachment/wiki/UsrpFAQ/USRP_Documentation.pdf

Negative numbers are 2’s complement.

Eric

On Wed, Sep 24, 2008 at 5:51 PM, Sebastiaan H. [email protected]
wrote:

Let’s say I take the signal from the cordic and pass it to the CIC
filter. When I want to have a look at the output of the CIC filter,
can I also do the above to get the output to 12-bit decimal?

All you need to do is divide by the normalization factor of what 1.0
really is in a fixed-point representation.

From the ADC, you will get a +/-2047 signal. To get this to decimal
format, you need to divide by 2047. Since you’re shifting over to the
left by 3, you need to divide now by 16383 to get your +/- 1.0 decimal
values.

Does that make sense?

Brian