Eclypse Z7 with AWG and Digitizer Zmods: making a 4-QAM MODEM

Table of contents

RoadTest: Enroll to Review the Digilent Eclypse Z7 and ZmodDigitizer

Author: Guillaume_Martin

Creation date:

Evaluation Type: Development Boards & Tools

Did you receive all parts the manufacturer stated would be included in the package?: True

What other parts do you consider comparable to this product?: Other FPGA/SoC development boards to which you connect external DACs/ADCs (Zybo Z7, ZedBoard Zynq-7000). Here, DACs and ADCs modules are easy to connect. In another price range, we could compare the board to Zynq UltraScale+ RFSoCs.

What were the biggest problems encountered?: The scattered documentation and version-dependant example designs.

Detailed Review:

1. Out of the box experience

What were my first impressions of the board when I opened the box for the first time?

  • The quality seems to be good, with sturdy and well placed connectors.
  • The two Syzygy connectors can be screwed to the main board, so everything is stable (which is great when connecting to the SMAs, it does not wobble at all).
  • The main board is quite large, a little larger than I expected.
  • The status LEDs are vertically aligned, which looks odd at first (but I will show why the LEDs are this way later).

One of the following pictures shows the board when held in a hand. This will give you an idea of the size of the board (16x9.9 cm).

{gallery}Out of the box gallery


Eclypse Z7 and Zmods: Eclypse Z7 board with the AWG and Digitizer Zmods attached (in hand for scale)


Eclypse Z7 LEDs demo: The two user RGB LEDs are lit on the bottom of the board as part of the demo design


Eclypse Z7 buttons demo: When a user button is pressed, a message is sent via UART as part of the demo design (shown on my computer using Termite connected to the Eclypse Z7 COM port)

The Eclypse Z7 board comes with a demonstration design in the flash. It is quite simple as it does not include the Zmods. It does two things: change the color of the user RGB LEDs and send a message via UART when a user button is pressed. However, it is useful to know that everything is OK with the board you have just received. That's fine, but what we want to do is generate and analyse signals using the Zmods.

2. Interface the Eclypse Z7 with WaveForms: our first signals

The Digilent website (WaveForms reference) states that "WaveForms is the virtual instrument suite for Digilent Test and Measurement devices.". It allows the user to interface Digilent hardware to a computer. This software supports the Eclypse Z7 and can turn the board into a USB oscilloscope and waveform generator. This can be very useful if you do not have such equipment at home, or if you need an extra channel for a project.

There is a tutorial from the Digilent website that explains how to interface the Eclypse Z7 with WaveForms. The tutorial is easy to follow and all you need (apart from the Eclypse Z7 and the Zmods) is a microSD card and some SMA cables. Once all the steps have been completed, the WaveForms software takes control of the Zmods modules. You can generate signals with the AWG module and display signals with the Digitizer module.

The user can control the output signal by setting various parameters such as frequency, amplitude, offset, waveform and others. The image below shows a 5 MHz sine wave generated by the AWG Zmod and sent to my benchtop oscilloscope. The signal is shown in yellow and its spectrum is shown in purple. The measured frequency is as expected (5 MHz).


We can also see two peaks in the spectrum at a higher frequency. The following image shows a zoom in on those two peaks. We can see that there is a 10 MHz gap between them. This is because the sine wave has been digitally generated, it is a sampled signal. So the peak at 117.9 MHz is the image of the signal at fsamplefsignal. The other peak is the next image of the 5 MHz sine wave (the spectrum of a sampled signal is periodic, the period being the sampling frequency). This would mean that the sampling frequency configured by this example design is somewhere around 123 MHz (the spectrum is processed by a benchtop oscilloscope using the math channel, more accurate results could have been obtained using a spectrum analyser).


I also tried to output a DC signal using the AWG Zmod to see if the sampling frequency could be seen. A 125 MHz frequency component can be observed. This is the maximum sampling rate for this module. And it is sufficient for many applications, especially if you use the Eclypse Z7 board for non-professional fun home projects, as the one we will see in the next chapter.

The WaveForms interfacing was a very good introduction to the Eclypse Z7 board and its capabilities, but we are not here to play with an application that has already been developed for us, we want to dig into the FPGA development and see if we can generate/measure signals ourselves!

3. Build an Eclypse Z7 project from scratch

As the main goal for this RoadTest, I decided to implement a simple 4-QAM modulator and demodulator in the programmable logic. This choice means that I will probably not have the time to interface the Zmods to the processing system, but I think it is worth it because with the modem I can play with some interesting SDR concepts and have a nice design in the programmable logic.

In the previous paragraph, I said “simple” 4-QAM modulator and demodulator because I had to let go of some things in order to have something to show in time. The list below shows what I simplified or removed:

  • Low carrier frequency.
  • Low symbol rate.
  • Low modulation order.
  • No RRC filtering (or other matched filtering).
  • No closed loops for carrier and timing synchronisations in the demodulator (manual correction by VIO).
  • Fully digital implementation (no hardware mixer or carrier generator).

Since I am much more comfortable with VHDL than Verilog, the whole design was done in VHDL and the whole project (Vivado 2021.2) is available on GitHub.

Before diving into the modulator and demodulator, I had to make two small modules to interface the user LEDs and user buttons in a clean way.

3.1. LEDs Dimmer

There are two RGB LEDs on the Eclypse Z7 board. These can be very useful to have a quick look at system flags, like the AWG output enable for example. The thing is that these two LEDs are very bright (to the point where it is uncomfortable to look at them directly). As I love my eyes, I had to create a small module to generate a PWM signal that could reduce the intensity of the LEDs.

For this project, I do not need variable intensity, so I designed the module to output a fixed 10% duty cycle on the LEDs. I measured the signal at the anode of the green LED (pin 6 in the following schematics) because it was the most accessible point, but remember that the waveform is inverted (the high time corresponds to 5V, when no current is flowing through the resistor and the low time corresponds to the voltage drop in the resistor when current is flowing, so the LED is lit).

We can see from the oscilloscope waveform that the LED is flashing at 1kHz (the flashing is not perceptible to the human eye at this frequency) and is OFF 89.97% of the time. The result is an LED with an acceptable brightness.



(See the LED_Dimmer.vhd file in the project's GitHub repository. Note that it instantiates the IP PWM_Gen_count.xci IP which is also in the repository).

3.2. Buttons debouncer

The buttons on the Eclypse Z7 are directly connected to the I/Os of the FPGA, there is no low pass filter on the board. What I want to do with the button is to toggle the enable input  of the AWG module every time the button is pressed. We need to debounce this button, otherwise the enable will be toggled several times and the final value will be random (depending on the number of bounces, the frequency of the toggles and the time the button is pressed).

What I have done to debounce the button is a simple solution: when the enable signal is toggled, a binary counter is reset. If the button is pressed again and the timer has not yet reached a predetermined value, the enable is not toggled again.

I have a clock frequency of 100MHz for this part of the design and set the binary counter top value to 50 million. This means that the enable signal is toggled at most once every half a second (no need to allow faster access for an enable input button). The button bounces will no longer have an unwanted effect.

As the AWG’s controller enable signal drives a relay, we want this signal to be driven by a stable and safe signal. Now that this is done, we can connect the AWG’s enable input without worrying about untimely switings.

(See the AWG_En.vhd file in the project's GitHub repository. Note that it instantiates the debounce_counter.xci IP which is also in the repository).

3.3. Interfacing the Zmods controller IPs

3.3.1. Zmod AWG

I added the Zmods to this project one at a time. First, I added the AWG Zmod to output the modulated signal. In the top entity of the Vivado project, I added the Zmod AWG Controller IP Core from Digilent and set all the required external I/Os signals as ports.

Now that the ports have been created, we need to update the XDC constraints file from the Digilent GitHub to set all the required I/Os. For this step, it is necessary to look at the Zmod and Eclypse Z7 schematics. It takes quite some time but it is not complicated. This step is very similar for both Zmods (constraints files are also available in the repository linked above).

With the constraints done, we need to connect all the necessary signals inside the PL to interface the Zmod controller. The IP needs three clock signals: one at 100 MHz to clock the control logic and two clocks at the sample frequency (in my design, this clock is 120 MHz) with a 90 degree phase shift between them. The use of a clocking wizard IP makes managing the clocks for this application quite simple.

The remaining main signals are a reset, an enable and the data AXI-Stream. This means that our logic has to drive four signals (reset, enable, data valid and DAC data). Setting up the project (I/Os constraints, clocking) is by far the most difficult part of using the Zmod AWG. Once this is done, using the controller IP is fairly straightforward: you provide data on the AXI-Stream and it is output by the DAC. For this project, the modulated signal is on AWG channel 1 and the symbol rate is on AWG channel 2.

The Zmod AWG Controller IP Core also has output status signals to inform the user's design when the configuration is complete or if an error has occured. I have never encountered a configuration error (I suppose it could easily be triggered by powering up the board without Zmod plugged in, but I have not tried this).

3.3.2. Zmod Digitizer

The Zmods Digitizer is a little trickier to interface but the steps are the same as with the Zmod AWG. First, instantiate the controller IP Core, then set the external I/Os as ports in the top entity of the design. Once this is done, update the constraints file (and remember to use the schematics to help you out). The final step is to connect the remaining signals to your design.

The main difference with the Zmod AWG is about the clocking. In the configuration used for this project, the sampling clock is generated by hardware on the Zmod digitizer's PCB. This difference makes the Zmod Digitizer a bit more difficult to use than the Zmod AWG. This online tutorial by Digilent was originally created to help the user migrate a design from Zmod Scope to Zmod Digitizer (two generations of Zmods with ADCs), but it contains a lot of very useful information even if you do not have a design using Zmod Scope (I had to create a design from scratch including the Zmod Digitizer and the information contained in the tutorial helped me a lot anyway).

However, this clocking difference can be useful if the DACs and ADCs (which is the case in this project), because the clock generated by the digitizer can be forwarded to the AWG.

The following figure shows the simplified architecture (resets, control, status and configuration signals/modules not shown) for a project including the Zmods AWG and digitizer.

The clocking (green in the diagram) consists of two input clocks: the 125MHz system clock from the Eclypse Z7 board and the sampling clock from the Zmod digitizer. A deskewing MMCM is instantiated inside the digitizer Controller IP and is completely transparent for the user. What we need to include are two clocking wizards with one input and one output each (125MHz to 100MHz system clock for the first and 90 degrees phase shift on the sampling clock for the second).

The data paths (red in the figure) can be very different from one project to another. For this RoadTest, the "ADC Sink" and "DAC Source" modules are the 4-QAM demodulator and the 4-QAM modulator respectively. The purpose of the DAC source module is to generate data that is going to be sent to the DAC. On the other hand, the purpose of the ADC sink is to collect and use the data sampled by the ADC.


3.4. The 4-QAM modulator

We want to generate a QAM signal in the programmable logic (PL). Such a signal has the following equation:


The data to be transmitted is coded in the I and Q signals. Their values must remain constant for a fixed period known to the modulator and the demodulator, called the symbol period. A symbol is a pair of I-Q values and is associated with binary data. In 4-QAM there are four different symbols, which means that one symbol carries two bits of data (in 16-QAM one symbol carries 4 bits of data). The I-Q values can be whatever the designer wants, as long as the demodulator and modulator know them.

3.4.1. Constellation diagram

All the I-Q values associated with the symbols of the modulation are usually plotted on a diagram called a constellation diagram. It shows the I-Q values for each symbol and is usually square-shaped for QAM (but not necessarily).

For this project, the 4-QAM constellation diagram is as follows:


This gives us the four following symbols:

  • 00: I=1, Q=1
  • 01: I=1, Q=-1
  • 10: I=-1, Q=-1
  • 11: I=-1, Q=1

Each symbol corresponds to a sinusoid where the amplitude is the distance between the symbol point and the origin of the diagram and the phase is the angle between the symbol point and the positive I semi-axis. In this case, all the symbols have the same amplitude and are separated from each other by 90 degrees of phase.

3.4.2. Simple QAM modulator architecture

The following figure shows the architecture of our simple QAM modulator. The VHDL code is divided into modules corresponding to the elements in the architecture. The list below briefly explains the purpose of each module (the files are available in the repository linked above and have explicit names):

  • Symbol rate generator: generates a periodic signal for symbol generation.
  • RNG: generates random symbols at the rate generated by the previous module.
  • Mapper: converts symbols into I-Q values according to the constellation diagram given in the previous section.
  • Direct Digital Synthesiser (DDS): synthesises the two carrier signals, a sine and a cosine.
  • IQ Mixer: multiplies the I-Q signals with the carrier signals and adds the two products.


3.4.3. Results

The following figures show the results of the 4-QAM modulator. The signals were captured with an oscilloscope in the analog domain or with an ILA after being sampled by the digitizer Zmod in loopback.

{gallery}Modulator results


Two consecutive identical symbols


90 degrees phase step between two symbols


180 degrees phase step between two symbols


270 phase step between two symbols


Modulated signal captured with persistence with the trigger on the symbol rate, we can see the four possible states corresponding to the four symbols


Symbol transition captured with an ILA (signal is output by the DAC and read back by the ADC before being captured by the ILA)


Time delay for the data to go through the DAC and come back from the ADC (the majority of this delay is inside the controllers IP Cores I think)

3.5. The 4-QAM demodulator

As already mentioned, the QAM demodulator developed for this RoadTest is a very simplified version. Timing and carrier synchronisations have not been implemented (at least, no automatic corrections). Timing synchronisation is not needed in our case because no RRC filter is used, the symbol rate is low and the modulation order is four. As for the carrier synchronisation, the correction is entered manually by the user using a VIO.

3.5.1. Simple QAM demodulator architecture

The following figure shows the architecture of our simple QAM demodulator. The VHDL code is divided into modules corresponding to the elements in the architecture. The list below briefly explains the purpose of each module (the files are available in the repository linked above and have explicit names):

  • Direct Digital Synthesizer (DDS): generates the carrier signals (sine and cosine) for the demodulator.
  • IQ splitter: does the opposite of the IQ mixer in the modulator.
  • Decimator LPF: low-pass filter with a lower sample rate at the output than at the input.
  • Demapper: converts IQ values back to symbols.


3.5.2. IQ recovery process

If we multiply the modulated signal by a regenerated version of the carrier signals (assuming that the regenerated carriers have exactly the same frequency and phase as those in the modulator), we get the following results:



If we only look at the first signal obtained (it is the same for the other one), we can see that we get a combination of three signals. The first one is the I-value over time divided by two (multiplying by two is not that difficult in an FPGA, just shift one bit to the left and it is done) and the other two signal components have sinusoidal oscillations at twice the carrier frequency.

As the symbol rate is low frequency compared to twice the carrier frequency, we can use a low-pass filter to isolate only the I(t) signal. The cut-off frequency of this filter has to be chosen carefully because there's a trade-off. If the cut-off frequency is low, the sinusoidal signals are almost fully removed but we loose I(t) harmonics, which are useful for restoring the square shape of the I(t) signal. On the other hand, setting a higher cut-off frequency will keep more I(t) harmonics, giving us a signal with sharper edges that will be easily transformed to the symbols values (because the transitions are time windows where the signal has an incorrect value, we want them to be the shortest possible) but the sinusoidal signal will not be reduced enough and we will keep residual oscillations.

This is the reason why having the symbol rate and the carrier frequency with very different values helps in having a simple demodulator.

The decimator LPF has two functions: the first is to perform the operation just explained and the second is to change the rate from sample rate to symbol rate. Note that a decimator filter has another huge advantage: since the ouput rate is lower than the input rate, there is no need to output a valid sample for every input sample, which means that a single DSP can process several input samples, reducing the total amount of DSPs required. In this project, the order of the filter is the same as the decimation factor. That means only two DSPs are used: my guess is that this is one for the coefficients/input samples multiplication and the other one for accumulation. A single-rate (same rate for input and output) filter uses as much DSPs as the order of the filter (for the same fequency response as the one used in this project, it means 50 DSPs vs. 2 DSPs).

3.5.3. Results

The following image shows a capture from an ILA core showing modulator's input symbols and demodulator's output symbols. We can see that the data sent is retrieved at the other end (with a time delay). Note that the I-Q values are around +/- 2500 but would normally be near a power of two (because I-Q with 4-QAM can be -1 or 1 represented as fixed-point). I guess the reason for that is the attenuation between DAC and ADC. I have not developped an automatic gain controller that would compensate for this attenuation (with automatic gain update if the attenuation changes).



4. Enclosure kit

Digilent sells an enclosure kit for the Eclypse Z7 and Zmods on their online shop. As I had lots of fun developping with the board and as they sent it for free, I purchased the enclosure kit. This transforms the evaluation board into a nice-looking device that looks like professionnal laboratory device.

The enclosure is made of a thick aluminum plate that is really hard. The two panels give the user all the information about the board's connectors and shows the status LEDs (this is the reason for the weird-looking LEDs I mentionned at the beginning). The SMA connectors from the Zmods can be connected from the back panel. Everything aligns perfectly between panels and connectors.

In my opinion, the only thing this enclosure is lacking are silicone bumpers so the device does not slide on the table.

5. Conclusion

The mechanical components of the board (connectors, enclosure) are of very good quality. I did not have any problems while plugging or unplugging anything. The Zmods are firmly attached to the Eclypse Z7 board.

The Zmods come with the schematics, user guide, documented and working IP Cores. This allowed me to interface the Zmods quite easily. As said before, the Zmod Digitizer is a bit harder to interface and to constraint and took me more time to setup than the Zmod AWG.

In general, Digilent gives a lot of documentation or examples, which is really good to start using their products. However, all of the ressources are scattered between the Digilent shop website, Digilent reference website, Digilent Github and Digilent forum. That makes it very difficult to find what you are looking for. For example, I found the information that the Eclypse Z7 can be interfaced with WaveForms days after starting reading the documentation when this information should (in my opinion) be one of the first you encounter as this helps you understanding the board before developping.

The Zmod digitizer controller IP Core documentation states that the supported Vivado version is 2021.1 but the more recent example design in the Digilent GitHub is on Vivado 2019.x. This means that you cannot use the example design for the Zmod digitizer. In fact, I had to start projects from scratch because I worked with Vivado 2021.1. Maybe providing a version of the example designs using HDL instead of block designs could be a good idea to be less version-dependant.

The Eclypse Z7 is a very versatile board. It is a development board that can be turned into a custom laboratory tool or be used as a prototyping platform. Furthermore, if you need an extra oscilloscope/signal generator channel, you can just plug it to your computer and interface it with WaveForms. Finally, I think it could be a very good educational platform for engineering students. It allows learning in C programming, HDL programming, signal processing, digital communications (UART, Ethernet, SPI, CAN, I2C) and more.

In conclusion, I would say that even if I haven't used all the features (1 GiB DDR3, Cortex-A9 PS, flash memory for boot, and others), I had a good time using this board with the two modules!

I hope I will find the perfect application to develop using this kit in the future. I think I will continue a bit this project (see appendix A) and, maybe, post another blog in the forum about it.

Appendix A. What's next?

The Eclypse Z7 board and the Zmods modules allow lots of different applications that can quickly become complicated. I am happy with what I came up with in a short time but I have not succeeded to do all I wanted before starting the RoadTest. The main missing functionality is a PS-PL interface that could connect the 4-QAM MODEM running in the PL with the Cortex processor in the PS. At first, I wanted to store ADC data in a BRAM (inside the PL). All this data would have been transfered to PS and then to PC by UART when requested by the user.

I will definitely continue playing with this board. And I consider adding the following functionnalities to the already existing project (the aim is not to have a working QAM MODEM, just to continue having fun):

  • PS-PL data transfer using BRAM as buffer.
  • PS-PL interface to enable/disable the MODEM.
  • Data transfer to a PC to plot constellation diagram in real-time on Matlab or Octave.
  • Add 16-QAM constellation.
  • Measure the attenuation at ADC's input and implement automatic gain control.