Generating a 30 MHz signal within the PYNQ framework

I was wondering if anyone had thoughts on if it would be possible to generate a 30 MHz sinusoid using a PYNQ platform?

I have an embedded application that requires real-time processing and signal generation so I figured this would be great for FPGAs. The first major technical challenge is to produce a 30 MHz signal. For this signal, I need to

  • start at the same phase (preferably 0 for sine wave) every time it’s triggered
  • have a minimum adjustment of 1 kHz (i.e. 24.001 MHz, 24.002 MHz…)

I am very new to PYNQ but I did get a Pmod DA4 working, however, the following code was the only way I could get the driver to generate a signal. As I am sure you can see, this was not fast and could only return a signal with an update of 2000 S/s.

# send the signal to the DAC
for i in range(yy.shape[0]):
    dac.write(yy[i])

At this point, my thought process for using PYNQ is to:

  • build an external signal generator chip from scratch and just control communication to it with PYNQ
  • Find a high-speed DAC and write a custom FPGA code to run it (I have never done this, but am willing to try it if I can).

Any thoughts or advice would be appreciated!

1 Like

Hi @adowney2 ,

I am interested in something similar: writing 8-channels with unique 30 kHz signals.

Have you made any progress?

My guess is that it’s not the DAC that’s the problem, but it’s that every single dac.write operation has to go through the full stack from Python->C->Zynq->MicroBlaze->SPI->PMOD.

You’d have to write a full cycle of your signal to the BRAM first, then have the FPGA read that out as its writing to the PMOD. I’ve seem some code snippets that show it’s possible to have a numpy array backed by memory shared with the FPGA, I don’t know if any of these examples also use that memory to write to PMOD. I intend to search more next week.

P.S., one thing worth trying is a list-comprehension.for loops in Python are notoriously slow, but list comprehensions can leverage some C optimizations: [dac.write(_) for _ in yy]
This is still a couple of order magnitudes slower than bulk memory transfers + bulk processing in the FPGA.

1 Like

Yes, writing to the DAC in this way will be relatively slow if using the PYNQ IOPs. You can create a custom hardware IP to drive this faster but I don’t think the DA4 will be good enough for your requirements. The Pmod uses a SPI interface which limits the speed you can drive the DAC at. In the base overlay, the clock is 6.25MHz, and there is some overhead communicating with the DAC, so you will need to use a different DAC/interface.

You need to determine the sample rate that you will need to use to accurately represent the sine wave and the number of bits you need. The sample rate should be at least twice the frequency of the sine wave, you will need to use a sample rate of at least 60 MHz.
This will help determine the DAC you need, and from there you can work back and figure out a platform to use.

At the high end, the RFSoC 4x2 has ~10Gbps DACs, but this is probably overkill for your application. www.rfsoc-pynq.io

Cathal

1 Like