Goal: Read in some RF pulses (at a repetition rate of 80MHz), classify the pulses (using some algorithms) in real time, and send pulses depending on the type of the input pulses.
Tool: RFSoC4x2 with PYNQ v3.0
My question:
Should I build my own design on top of the base overlay, especially the radio subsystem, or should I start from scratch?
Specifically, I was wondering whether I should preserve the transmitter and receiver block in my design, or I should use the bare rfdc core and design my own “transmitter” and “receiver”? Is this a matter that depends on the specific application?
There is a “packet generator” IP core in the receiver subsystem. What does it do? I couldn’t find related documents. Is it not open-source? If that is the case, then does it mean that we have to stick to the radio subsystem in the base overlay design rather than designing our own?
Hi,
You could build your own design on top of the base overlay. This block design is heavy, I would be time consuming to build another one from scratch.
Specifically, you would have to change the transmitter block, I did some explanations here:
For the packet generator blocks, I did not find their codes. It seems they are formatting the frames received by the ADC to be understood as complexes. When I deleted that block, the 2 DMA blocks were not able to save the complexes received, they did not detect the values.
Thank you for your comments! I have checked your blog. It really helps.
I do have some more questions. I would appreciate it if you could leave some comments:
Are you saying that if we only use real signals, then we can safely delete the packet generator block? In my application I only need real signals, so I would be very happy if that’s the case.
Have you tried using ILA to capture the data or simply reading them in the PYNQ Jupyter notebook to check the data format? What do you mean by “they did not detect the values”? Is it that you read the values but they were in the wrong format, or did it simply throw an error?
If I were to transmit signals from memory, does it suffice to connect DMA (AXIS_M2SS) to the RFDC block (S_AXIS)?
Firstly, I worked on a RFSoC 4x2 project where I tried to send complexes from a webcam of board A to board B via the analog ports. I was not able to finish this project, I had issues with analog frequency modulation in the reception. So I am not an expert of RFSoC 4x2.
Then:
even if you use real signals, the ADC will detect things and need a packaging block to formate what is the amplitude and the frequency. Even if the imaginary part is null, I think the receiver needs this packet generator block to understand what is the value of the real part in the frame received.
Why do you want to delete that packet generator? Reception seems to work with it. Modify reception after you designed a proper emission part (that requires a lot of work as there is like nothing in the base design, in the transmitter block).
“they did not detect the values” → values where in the wrong format. When I used the “transfer” function, the DMAs where empty (transfer is stuck to an infinite wait() ) while I had something before deleting the block.
What do you mean? Connect the DMA in AXI-STREAM protocol to the RFDC port s00_axis? I do not know what is the AXI protocol required for s00_axis.
Even that, what will be the frequency and amplitude of the signal the DAC will output? You need to define them
Do you mean that even if we are not sure about the exact function of the packet generator IP, we still need to use it, both for ADC and DAC?
The base overlay does not have the packet generator for DAC because it does not transmit signals from memory. Rather it uses the “amplitude controller”, as you also pointed out.
If we want to transmit custom data from memory, do we also need the packet generator?
Yes, I mean connecting the DMA AXIS_M2SS to the RFDC port s00_axis. Because they both use the AXI-stream protocol. Have you tried this before?
What do you mean by frequency and amplitude of the signal? In my application I bypass the mixers. I directly sample the signals and directly send them, without mixing. The data to transmit are defined in the memory, probably by output_buffer = allocate((size,), dtype=np.int16).
I guess the reason why we have to use the packet generator block is because it has the TLAST signal, which the RFDC block does not have. DMA would get stuck if the TLAST signal is absent.
For the block “packet generator”, I just know that the reception works with it. I did not see the interest in deleting it, so I kept this block. I do not know precisely what it does.
For the DAC, you can directly connect your DMA to the RFDC in AXI-STREAM protocol via both ports mentioned. However, what will the DAC transmit as an analog signal? A sinusoidal signal? At which freqency? Will the amplitude be your real value from the DMA? But what if you have a float real value?
And for the ADC, at which frequency should it focus? What is the carreer frequency?
How do you want it to recon, detect the signal from the DAC?
And what if there is noise in the channel between transmission and reception (I guessed you connected 2 RFSoC 4x2 via a coaxial cable, one at a DAC and the other at a ADC) ? Do you accept that you transmit a real “-19.78” but it is received as a “-18.43” ?
As I said, I bypass the mixers, meaning that the carrier frequency is zero. The transmitted signal is defined in the memory, which is some waveform to be directly transmitted and is not sinusoidal. Similarly, the analog signal is directly sampled without first being downconverted by any mixers.
I am now trying the design (with packet generator for ADC/DAC). I will update this post if the design does or does not work out. Thanks!
Hey, could you get your design to work? I am trying a similar thing. Any help is appreciated. What changes have you made in the base overlay block design?
I have used ILA to check the signals of packet generator and amplitude controller. Here is something I found out:
If you want to read data to pynq jupyter notebook, the packet generator in the base overlay is the way to do it. It enables the TLAST signal at the end of the packet with a certain size. You write the packet size to offset address 0x00, and write 1 to the offset address 0x04 to start generating the packet.
The amplitude controller is basically giving a constant AXI stream signal without TLAST. It provides a constant stream, say, 0x7fff7fff (you can set it with pynq by amplitude_controller.write(0x04, gain)), to the RFDC. And you enalbe it by amplitude_controller.write(0x00, 1). The constant is mixed with a sine wave defined by the mixers. Actually the constant is just the amplitude of the resulted sine wave, because what mixers do is just multiplying the data with a sine wave. This is why it is call “amplitude controller”.
Since RFDC is not receiving TLAST signals, there is no need to use packet generator before the DAC. Just feed s_axis with your data, probably provided by a DMA or your custom IP core.
With these facts clear, I can build my own block design from scratch, rather than building it on top of the base overlay. I will not be using other peripherals anyways for now. The radio block in the base overlay is a good reference and a starting point though.
It is always useful to use an ILA. You can figure out almost everything with ILA.
Okay I’ll just clarify once to make sure both of us are in the same page. I hope that’s okay. I just started working on the board.
What you are saying is the packet generater is only required if we want to create a pynq overlay and visualise the signals using python. But you are using ILA for that purpose, hence are going to remove the packet generator from the diagram.
Next regarding the amplitude controller, it generates a stream of data signals without the TLAST signal.
You are getting that stream of data signals from some dma or custom IP that you are feeding into the s_axis port of the dac channel.
Is this what you meant in ur post? Sorry again if u feel I am just reiterating the things.