Skip to content

Getting Started

Benjamin Saunders edited this page Mar 18, 2026 · 1 revision

Installing RFBuilder

Configuring the Board

There are a few things you will need to do to load the RFBuilder firmware / hardware onto your RFSoC.

To configure your board to run the RFBuilder firmware and hardware, you must first load the files onto a micro SD card.

  1. Go to the latest release of the RFBuilder library (link TBD), and download all of the files.
  2. Load a micro SD card into your computer. It must be in FAT32 file format, with nothing in the root directory.
  3. Place all RFBuilder files onto the SD card, there should be 4 files with extensions .bit, .bif, .BIN, and .cfg.
  4. Configure the network settings on your board by following the steps below:
    • Plug the RFSoC directly into your computer using an Ethernet cable.
    • Open command prompt / your terminal of choice, and type ipconfig (ifconfig for UNIX systems)
    • Find the network interface that corresponds to your board (if you do not know which one it is, unplug the board and see which one dissapears!)
    • Take note of the following values: ipv4 address, and subnet mask
    • Open the RFBuilder.cfg file that was downloaded with the board, and replace the ip address and subnet mask fields with the values you just found.
    • Save and Exit.
  5. Ensure the BOOT switch on your RFSoC board is set to SD instead of UART.
  6. Load the SD card into the slot on your board, and power it on. You will know RFBuilder is loading if the OLED display lights up with RFBuilder!.
  7. Once the board has fully initialised, the OLED display will show the IP address that it has been assigned.

First RFBuilder System

Once the firmware has been uploaded and your RFSoC is successfully displaying the Ready! message, you can begin using the Python library.

Every single RFBuilder system configured in the RFBuilder Python library will follow the same 3 basic steps. There will be a bit more to it when creating more advanced systems, but at its core, you will always perform the following 3 actions.

1. Create a new RFBuilder system.

Creating a new configuration in the RFBuilder system begins by initialising the RFSoC board that you are going to use.

At the moment, the only supported board is the RFSoC4x2 development board from RealDigital. To initialise it, you simply create a new instance of the RFSoC4x2 class in a new, empty python script:

from RFBuilder import *

board = RFSoC4x2()

Then, use that to initialise the new RFBuilder instance. Each instance takes in 3 variables:

  1. board: Is the object of the RFSoC board that you are using (as created above).
  2. ip_address: Is the IP address of the RFSoC board that is displayed on the OLED once the RFSoC board as fully booted up.
  3. port: This is the TCP/IP port used for communications. For now, this will always be 8080.

Using this information, we can create our RFBuilder system using the following instructions:

from RFBuilder import *

board = RFSoC4x2()

rf_builder = RFBuilder(board, "x.x.x.x", 8080)

2. Configure the blocks in your system.

Now that we have an RFBuilder system set up, we can start adding blocks to it. If you are unfamiliar with how the blocks work, you should first read the Home page, and then investigate the individual block types further in their respective chapters if required.

Lets start by creating a basic RFBuilder system that will verify that the firmware on your RFSoC is behaving as expected.

The blocks we will use to do this are the ArbitraryWaveformGenerator (AWG) block, and the DataLogger block. Exact specifications and configurations for these blocks can be found in their respective chapters, but for now, a small description for each block can be found below:

  • AWG : The AWG block generates a waveform based on its frequency and wavetype parameters, and outputs it from its single output port.

  • DataLogger : The DataLogger inputs data from its single input port, and hands it back to your python script through its .read() method.

The system we create will simply connect the output from the AWG to the input of the DataLogger. This will not utilise the RF front end of the RFSoC, but will provide a good baseline for your understanding, as well as ensure the RFBuilder firmware is working as expected.

To begin, we must create the ArbitraryWaveformGenerator block with our desired waveform type and frequency:

awg = ArbitraryWaveformGenerator(WaveType.SINE, 500e6)

Then we register it with our RFBuilder instance:

rf_builder.register_block(awg)

Next, we must do the same with our DataLogger, like this:

logger = DataLogger()
rf_builder.register_block(logger)

We can then connect these blocks using the RFBuilder's register_connection(input, output) method:

rf_builder.register_connection(awg, logger)

Finally, lets print the rf_builder instance to see what has been loaded.

print(rf_builder)

After following these steps, you should arrive at the script shown below. You can also run it now, it wont yet upload to your board, but at least you can test to see if the package is working properly.

from RFBuilder import *

board = RFSoC4x2

rf_builder = RFBuilder(board, "x.x.x.x", 8080)

awg = ArbitraryWaveformGenerator(WaveType.SINE, 500e6)
rf_builder.register_block(awg)

logger = DataLogger()
rf_builder.register_block(logger)

rf_builder.register_connection(awg, logger)

print(rf_builder)

3. Programming the RFSoC

Now that we have a fully connected multi-block system, lets upload it to the RFSoC, and read the data from our DataLogger.

This can be done very simply using the following command:

rf_builder.update()

This command packages up your system and transmits it to your RFSoC board. The python RFBuilder instance keeps track of any changes made after this point, so if you make any changes and re-upload (e.g awg.set_freq()), it will only upload what is necessary. Once added to the script, we end up with the following code:

from RFBuilder import *

board = RFSoC4x2

rf_builder = RFBuilder(board, "x.x.x.x", 8080)

awg = ArbitraryWaveformGenerator(WaveType.SINE, 500e6)
rf_builder.register_block(awg)

logger = DataLogger()
rf_builder.register_block(logger)

rf_builder.register_connection(awg, logger)

print(rf_builder)

rf_builder.update()

Once uploaded, it will begin running automatically. You can now read the data from the logger with logger.read(), and use it however you would like. The following matplotlib script will continuously read from the logger and plot the data for you:

import matplotlib.pyplot as plt

plt.ion()
fig, ax = plt.subplots()
line, = ax.plot([], [])
plt.show()
while True:
    wave, time = logger.read()
    line.set_data(time, wave)
    ax.relim()
    ax.autoscale_view()
    fig.canvas.draw_idle()
    fig.canvas.flush_events()

If all is working as expected, you should see the following waveform:

INSERT WAVEFORM IMAGE HERE

This concluded the basic use of the RFBuilder system. Another example will be walked through below that explores the usage of the RFSoC's RF capabilities. More examples can also be found in the Examples chapter, that cover a few of the more specific use cases.

RF Integration

Every single RFSoC board has a set of ADCs and DACs that can be utilised. These are pre-programmed for you, based on the type of board you have initialised your system with. For the RFSoC4x2 board, there will be 2 x DACs and 4 x ADCs.

You can access the DACs and ADCs on your board by executing rf_builder.get_dacs() and rf_builder.get_adcs() respectively. These commands will return the DACs and ADCs as a list of RFBlock objects, in order of their appearance on your RFSoC. i.e. rf_builder.get_dacs()[0] and rf_builder.get_dacs()[1] is 'dac_a' and 'dac_b' on your board respectively.

If you wish to print all of the RF terminations on your board, you can use the following script:

dacs = rf_builder.get_dacs()
print([dac.name for dac in dacs])

adcs = rf_builder.get_adcs()
print([adc.name for adc in adcs])

Each DAC and ADC retrieved through this instruction acts as an individual block in the RFBuidler system. That means that we can connect them to other blocks in the same was as we did above.

Using this information, let's build a simple feedback system that sends data out of the DAC and then reads it back in from an ADC. To manipulate the data inside the RFSoC, we will use the ArbitraryWaveformGenerator and DataLogger blocks from above. The AWG will provide waveform data to the DAC, which will then be connected to an ADC using an SMA cable, which will then sample the waveform and output the data to the data logger module.

The image below represents the system that will be created, as is followed by the python script to connect the blocks as described above.

*** IMAGE HERE ***

from RFBuilder import *

board = RFSoC4x2()

rf_builder = RFBuilder(board, "x.x.x.x", 8080)

dacs = rf_builder.get_dacs()
adcs = rf_builder.get_adcs()

awg = ArbitraryWaveformGenerator(WaveType.Sine, 1200e6)
rf_builder.register_block(awg)

logger = DataLogger()
rf_builder.register_block(logger)

rf_builder.register_connection(awg, dacs[0]) ## dacs[0] = dac_a on the RFSoC4x2
rf_builder.register_connection(adcs[0], logger) ## adcs[0] = adc_a on the RFSoC4x2

rf_builder.update()

Clone this wiki locally