Showing results for 
Search instead for 
Did you mean: 

RF Data Converter IP Example Simulation Walkthrough

5 0 400

Hello again and welcome to the latest in the RF Data Converter Blog series.

This time we are going to take a look at the RF Data Converter IP example design simulation testbench.

The aim of this blog is to show how it is built and the mechanisms it uses to exercise the IP. I think it is worth going through because if the testbench is well understood it can serve as a good template for building the RF Data converter IP into your own simulation setup.

I am not going to do a deep dive into everything that is there instead, I aim to show the mechanics of the simulation. You are of course free to go deeper into the testbench RTL yourself.

As you might already know the IP example design comes with a complete testbench. This testbench provides stimulus generation and capture in the simulation for exercising both ADC and DACs. The simulation has in-built self-checking so it can be used to validate your IP settings.

Let’s give ourselves a high level overview of the example design testbench.


At the IP example design level, we have the IP itself and the stimulus and capture blocks, which are just large block RAM arrays.

There is also a SmartConnect block that connects to the AXI4-Lite port of the IP.

So, what is needed from the testbench is:

  • Clock Generation for all of the clocks in the design. ADC and DAC tile inputs, AXI Streaming interfaces and an AXI4-Lite interface.
  • A way to load the stimulus or source blocks.
  • A way to apply “real” signals to analog inputs and a way to convert real signals from the DAC to digital buses so that we can check them.
  • Most importantly, a sequencer is needed to manage the simulation.
  • A way to inspect the capture or sink blocks.

Let’s explore the testbench a little bit. All of the source files for the testbench are contained in the imports directory in the example design project.

The top level testbench is contained in the SystemVerilog file. We will not go through it exhaustively line by line or anything like that. This level just connects up the main blocks. Let’s take a look at the most important parts of the simulation functionality.


Clock Generation

We’ve got a pretty straight forward block to create all of the necessary clocks in the simulation. What is nice about it is that there are inputs with the _phase suffix that allow the user to set a high and low time for the clock. This is used to create the desired frequency for each tile and stream clock.




We can check this in the simulation to ensure that it is doing what we expect.

In this case we can see that the DAC sample clock is running at 6.4GSPS and the stream clock is running at a divide by 16 of this rate.


Stimulus Generation

In the simulation the ADC and DAC are treated separately. There is no loopback done in this case.

There is a source for the DAC and ADC.

For the ADC there is the, which houses the In the tile source we are providing a sine look-up table (LUT). In this case we cycle through this LUT and produce the output sine wave.



This sine wave is outputted to the top level of the testbench. We can convert it to a real number so we can force it onto the Analog Input of the ADC at the UNISIM model level of the tile in the demo_tb.



For the DAC it is just a case of writing the data into the DAC source block in the example design over the AXI interface. At the demo_tb level we can convert the DAC analog signals from real to bits and apply them to the DAC sink inputs.


Testbench Sequencer

Now that the clocks are running in the simulation and we have talked about the data sources, we can move on to the main part of the test bench.

If you go to the file called you will see how we set up and control the simulation. This file uses some SystemVerilog tasks which allow us to access the RF Tiles to do some setup of the tile. There are also other tasks to control the simulation. We’ll walk through the simulation and discuss these where needed.

If you look at this file you will see that it uses parameterized addressing to allow us to work with the various sub-blocks in the testbench over AXI4-Lite. These will be used by the various tasks to control the simulation.



The first thing that the sequencer does is to apply a reset to everything in the testbench. Then it does a write to the tiles to enable the simulation speed-up. This has the effect of shortening the start-up of the tiles by reducing the power supply trim time and reducing the time for ADC calibration. The Simulation only lets the tiles get to state 1 of the startup state machine for the IP.



After this step it does some setup of the tiles, and starts to turn on the sources and sinks in the testbench. It will also begin to load the DAC source memory.



It is good practice to print the simulation time regularly at each step. This way we can check the waveforms as needed.

You can see that it finishes setting up the IPs and begins writing to the DAC stimulus block around 169us. DAC source memory is at the base address 0x300000000.



Next we start the clocks to the tiles and let the ADCs and DACs run to the clock detect step.



Once this step is done, we start the DAC sources and run the DACs all the way to the end of their start-up FSM:



If we look at the waveform we can see the tones getting sent in and the DAC output bus running.

The 25Mhz/50Mhz/100Mhz/200Mhz can be seen here.



After this we repeat the process for the ADC:



You can check this in the waveform after it runs through. In this case the vout_00 and vout02  buses are the outputs of the ADC source in the simulation.

I have also included a screen capture of one of the 8 samples per AXI stream word to show that the ADC is converting the tones properly. 



Data Sinks and Checkers

Both ADCs and DACs have a set of sink blocks in the demo_tb.

Inside these blocks the data is scaled, and we do an FFT. This lets us know that the tone is correctly converted.



These blocks manage the error counters. If all is correct, the sequencer stops the simulation.




I hope this blog entry has given you a good insight into the IP example simulation. There is a lot more to explore but this should give everyone a good start-point for understanding how the simulation works and perhaps you can take some of these techniques for your own simulation test-benches.