Question about introduction Jupyter notebook and the 4x2 board

I have a RealDigital 4x2, and am going through the tutorials. The first tutorial (01_rf_dataconverter_introduction.ipynb) is pretty simple:

  1. load the “base” firmware, setup the rf clocks
    2, set the output tones frequencies using the base.radio.transmitter.channel[0/1].dac_block.MixerSettings[‘Freq’] method
  2. set the transmitter control.gain and control.enable to true
  3. set the number of samples and take data

The notebook says that the mixer frequency of the receiver ADC is set to 1228.8MHz, at the center of the first Nyquist zone given a sampling frequency of 4x that number. Makes sense.

But I’d like to vary this. To do this, I first printed the value using
print(str(base.radio.receiver.channel[2].adc_block.MixerSettings[‘Freq’]))

and it comes back as -1228.8, which is what the documentation says the receiver mixing frequency should be. Why is it -1228.8 and not 1228.8? (Is this a stupid question?)

When I take data, I indeed see receiver data that is consistent with the difference between the DAC frequency as set in MixerSettings, and the ADC MixerSettings[‘Freq’] value.

When I then try to change the ADC mixer frequency, for example doing this:

base.radio.receiver.channel[2].adc_block.MixerSettings[‘Freq’] = -1000

I read it back and it’s indeed set to -1000, then I take data.

But the data coming back is still apparently being digitized and mixed with a 1228.8MHz tone.

So either base.radio.receiver.channel[2].adc_block.MixerSettings[‘Freq’] is not how you change the mixing frequency, or perhaps the classes that are made aren’t connected to the FPGA ADC tiles? Or maybe I’m just making a stupid mistake, which is entirely possible!

Any ideas would be much appreciated.

Thanks!
Drew

Hi,
If I understand correctly, you are using the provided notebook “RFDC introduction”. You want to modify the frequency of the signal sent. For that, you need to modify the frequency from the transmitter, the DAC, and not from the receiver, the ADC, via
base.radio.receiver.channel[0].dac_block.MixerSettings[‘Freq’]=1000 (for example)

Use channel 0 of the dac class because you connected the DAC port B to the ADC port B, to channel 2 of the adc class.

About the negative frequency, why do you print your value with ‘str()’?

Hi. Yes, I know how to change the transmitter frequency and that works fine.

What I am doing is to connect the DAC output to the ADC input and digitize what comes out of the DAC. The ADC uses 1228.8 MHz mixing frequency and mixes this with the incoming frequency, so when you look at the data you will see a waveform that has a frequency which is the difference between the DAC output and 1228.8MHz.

When I tried to change the 1228.8 to something like 1000, and take data, the incoming waveform still has a frequency that is the difference between the DAC output and 1228.8. So either it’s a bug, or I’m not using the python objects correctly, or the software/firmware is just not set up to change that mixing frequency and it is therefore hard coded in. Or some other reason I can’t guess at.

Thanks,
Drew

Sorry, I forgot to answer your question about why I print with str(). It’s because the value that comes back is a float.

Drew

Also…I would love to know how to find the address of the ADC mixing frequency in the Xilinx base project, then I could just use the MMIO library to peek and poke at it. I’m trying to learn how to do this now by playing around with Vivado but I’m still on the shallow part of the learning curve! :slightly_smiling_face:
Drew

In Vivado, did you check the adress editor tab to search for that adc address?
The ADC saves its received complexes in DMA blocks. You can get these complexes via the function base.radio.receiver.channel[2].transfer(number_samples), described here:
(RFSoC-PYNQ/boards/RFSoC4x2/packages/rfsystem/package/rfsystem/hierarchies.py at master · Xilinx/RFSoC-PYNQ · GitHub)

Hi. I looked in the address editor but didn’t see anything labeled as obviously the address of the mixing frequency. What should I search for?

Do you have any idea why setting the following:

base.radio.receiver.channel[2].adc_block.MixerSettings[‘Freq’] = 1000

doesn’t work? Is there something else I have to set to be able to change that frequency on the FPGA. Again, I can set it to 1000 and read it back and it’s at 1000, but when I take some data, it’s still using 1228.8.

Also, do you know whey the default is -1228.8 and not 1228.8?

Thanks again!
Drew

1: Maybe you cannot have access to the address of the mixing frequency. You could maybe change its value via the block RF Data converter in the radio block of the block design.

2+3: I suppose something: in the notebook, only the frequency of the DAC is set up. So maybe the DAC indicates to the ADC which frequency to use to demodulate in frequency the analog signal.

It could be useless to change the mixing frequency of the ADC as it will automatically be changed by the configuration from the DAC to execute a proper demodulation, by going back to 1228.8.

And for the negative value, you read it for the ADC. So maybe it is negative to demodulate the signal which was modulated at the frequency of the positive value.

| matthew
August 21 |

  • | - |

1: Maybe you cannot have access to the address of the mixing frequency. You could maybe change its value via the block RF Data converter in the radio block of the block design.

You mean rebuild the Vivado project with a different value? Yes that’s possible, but if I could learn how to find the address in the design, then I could use the MMIO library to change it directly from the notebook. Do you have any suggestions how to do this, what to search for in the address editor (which I presume is the tab that Vivado gives me when I open base.bd, right?)

2+3: I suppose something: in the notebook, only the frequency of the DAC is set up. So maybe the DAC indicates to the ADC which frequency to use to demodulate in frequency the analog signal.

It could be useless to change the mixing frequency of the ADC as it will automatically be changed by the configuration from the DAC to execute a proper demodulation, by going back to 1228.8.

I’m pretty sure that when I change the DAC frequency, it changes what is output. That is, when I set the frequency to e.g. 1G, and I look at the output on a fast oscilloscope, I see a 1G tone. So I don’t think there’s any coupling between the DAC and ADC mixer frequencies - the ADC mixer frequency stays at 1228.8MHz no matter what you do in the python libraries.

Is there a tutorial as to how to build a project like ”base”?

Thanks again!
Drew

As you already have the base architecture, you can modify the block design. Then, you right click on the block design and you “reset output product”. Then you “generate output product”. When it is finished without error, you can “generate bitstream” with all the steps required.

If everything finished without issue, you can place the .bit and .hwh files generated in the FPGA and use this new architecture.
But to generate this bitstream, you will need an enterprise license. Thus, I warn that changing architecture to test if you can change the mixing frequency of the ADC might be long. You might prefer waiting for a more accurate and efficient answer than my previous suppositions.

You can use this video to see how to generate the bitstream:
(https://www.youtube.com/watch?v=hbPcIxW-Gtg)

Thanks. But I don’t know which parts of the block design to modify to get to the ADC mixing frequency. That’s what I need help with. If there is any documentation that you think would be best for me to read, that would be great.

Thanks again!
Drew

Did you check the block “RF Data converter” in the “radio” block of the block design?

Hi Drew!
I believe you need to make changes in the hierarchies.py file here: RFSoC-PYNQ/boards/RFSoC4x2/packages/rfsystem/package/rfsystem/hierarchies.py at master · Xilinx/RFSoC-PYNQ · GitHub

The way to decide the center frequency and Nyquist Zone settings is explained better in the FrequencySelector class in the spectrum_sweep.py file, which is used in nb3 in the same example: RFSoC-PYNQ/boards/RFSoC4x2/packages/rfsystem/package/rfsystem/spectrum_sweep.py at master · Xilinx/RFSoC-PYNQ · GitHub

Thanks! I will look at this now. But in the meantime, can I ask a few simple questions about how the system works:

In the introduction notebook, I turn on the 2 DACs by doing this:

Hi. Thanks for this tip. I took a look, but still have a question about it.

In my notebook, I use the base.bit project and load it like this:

from pynq.overlays.base import BaseOverlay
base = BaseOverlay('base.bit’)
base.init_rf_clks()

Then I set the transmitter and receiver frequencies for the 1st Nyquist zone as in the code below. I assume that for the 1st zone, the DAC frequencies are >0 and the ADC are <0, which seems to be what’s in the spectrum_sweep.py code, is that right?

base.radio.transmitter.channel[0].dac_block.MixerSettings[‘Freq’] = 800 # MHz
base.radio.transmitter.channel[1].dac_block.MixerSettings[‘Freq’] = 1400 # MHz
print("DAC 0 "+str(base.radio.transmitter.channel[0].dac_block.MixerSettings[‘Freq’]))
print("DAC 1 "+str(base.radio.transmitter.channel[1].dac_block.MixerSettings[‘Freq’]))

base.radio.receiver.channel[2].adc_block.MixerSettings[‘Freq’] = -1000.0
base.radio.receiver.channel[3].adc_block.MixerSettings[‘Freq’] = -1000.0
base.radio.receiver.channel[0].adc_block.UpdateEvent(1)
base.radio.receiver.channel[1].adc_block.UpdateEvent(1)
print("ADC 2 "+str(base.radio.receiver.channel[2].adc_block.MixerSettings[‘Freq’]))
print("ADC 3 "+str(base.radio.receiver.channel[3].adc_block.MixerSettings[‘Freq’]))

The print statements returns:

DAC 0   799.9999999999883
DAC 1   1399.9999999999884
ADC 2  -999.9999999999941
ADC 3  -999.9999999999941

Then I turn on the 2 DAC transmitters:

I’m very sorry, I have typo in the python code below. When I call UpdateEvent with the correct channel, it definitely does change the ADC mixer frequency. So sorry about that, your tip was a great help!

Drew

2 Likes