In Part 1, we looked at how to add UberDDR3 to the Vivado IP Catalog, making it easy to use in Block Design, especially for integrating with MicroBlaze. We even ran a simple "Hello World" program to test everything worked well.
Now here in Part 2, we’re ready to take it up a notch with more advanced projects! First up is a Dhrystone test, where we'll compare the performance of MicroBlaze with UberDDR3 against MicroBlaze with MIG. This test will also give us a look at how much FPGA resource UberDDR3 uses compared to MIG!
The second project is an Ethernet local echo server, designed to push memory limits of the FPGA — something you couldn’t normally do without DDR3 memory. This project will really show how convenient UberDDR3 is for handling data-heavy applications.
Let's get started!
Table of Contents:
I. Demo Project 2: Dhrystone Test
We'll be building on the exact project from Part 1, where we implemented the "Hello World" program on the Arty S7-50. To get similar results, it’s a good idea to follow those steps in Part 1 first before moving forward here:
1. We will create a new application project for the Dhrystone test. Click on New > Application Project
Since we've already added the XSA file to this workspace, we can reuse it. In the Select a platform from repository tab, simply choose the artys7_50_bd_wrapper platform:
Enter your preferred name for the application project. For example, I named mine artys7_dhrystone:
For project template, choose Dhrystone:
2. Once the directory and files are created, open the linker script lscript.ld in the src folder. You'll see that it automatically recognizes uberddr3_axi_0_ddr3_mem as a memory region. All sections are already mapped to UberDDR3 by default — exactly what we need!
Build the program and launch it on the hardware. Then, click the play button to run the entire program:
The Dhrystone results will be displayed in the Vitis Serial Terminal, which we previously connected to the serial line for the Hello World program:
I.I UberDDR3 vs MIG: Dhrystone Performance
As shown above, the DMIPS/MHz of MicroBlaze with UberDDR3 is 0.3154. To compare, I created the exact same project but swapped out UberDDR3 for MIG.
As shown in the linker script below, you can see that all memory sections are now mapped to MIG. Running the Dhrystone test again, the results are displayed in the Vitis Serial Terminal:
Dhrystone test performance results:
MicroBlaze with UberDDR3 = 0.3154 DMIPS/MHz
MicroBlaze with MIG = 0.3061 DMIPS/MHz
MicroBlaze with UberDDR3 edges out MIG slightly! It may be a small difference, but it proves that UberDDR3 can hold its own right alongside MIG.
I.II UberDDR3 vs MIG: Hardware Utilization
Next, let’s compare the hardware utilization of UberDDR3 and MIG. Here’s the utilization report for UberDDR3 (uberddr3_axi_0)
Shown below is the utilization report for MIG (mig_7series_0):
Summary:
UberDDR3: Slice LUTs = 3083, Slice Registers = 2743
MIG: Slice LUTs = 4576, Slice Registers = 4047
UberDDR3 uses 32.63% fewer Slice LUTs and 32.33% fewer Slice Registers than MIG.
Once again, UberDDR3 takes the lead! 😄
II. Demo Project 3: Ethernet Echo Server
Our next project involves creating an Ethernet echo server. The aim is to develop a memory-intensive application that typically requires DDR3 memory. We’ll be using a template project from Vitis called the lwIP Echo Server.
For this project, I’ll be using the ALINX AX7103B FPGA board:
II.I Vivado Block Design for Ethernet Echo Server
To begin, we need to implement the block design in Vivado by adding all the necessary IPs and peripherals, including the MicroBlaze processor:
1. Create a new project in Vivado and add the UberDDR3 repository to the Vivado IP Catalog by following the steps outlined in Part 1.
2. On a new Block Design, add the MicroBlaze IP then run block automation. 16KB for both local memory and cache configuration is enough, then make sure to check the interrupt controller option:
3. Do not run the connection automation just yet. Instead, open the Clocking Wizard block and change the input frequency to 200MHz, which is the input differential clock for the AX7103B board.
On the Output Clocks tab, enable 4 clock outputs with the following settings:
controller_clk = 100 MHz
ddr3_clk = 400 MHz
ref200_clk = 200 MHz
ddr3_clk_90 = 400 MHz, 90° phase shift
3. Add the UberDDR3 IP, open the block to customize it:
The ALINX AX7103 FPGA board features two Micron 4Gbit (512MB) DDR3 chips, providing a total of 8Gbit of memory. It supports a maximum operating clock speed of 400MHz, which translates to a data rate of 800Mbps. Basically, there are two x16 DDR3 chips for a total bus width of 32 bits:
The DDR3 RAM can run at clock input of 400 MHz (or 2500 ps for the DDR3 Clock Period). Since UberDDR3 is a 4:1 memory controller, the controller user interface will run at 1/4 of DDR3 clock thus 100 MHz (or 10000 ps for the Controller Clock Period).
Row, Column, and Bank bits can be left as is, but we need to change the Row Bits to 15 since that is the number of available rows in the DDR3 chip of AX7103 FPGA board.
There are two x16 DDR3 chips for a total bus width of 32 bits, thus Byte Lanes of 4.
ECC Enable can just be set to zero (ECC disabled). Possible options are:
1 = Burst-granular Side-Band ECC (refer to this blog post)
2 = Word-granular Side-Band ECC (refer to this blog post)
3 = Inline ECC (refer to this blog post)
There are three check boxes:
Skip Internal Test = Make sure to check this if UberDDR3 will be used with MicroBlaze. The built-in self-test of UberDDR3 takes more than 2 seconds and that long start-up can cause MicroBlaze to fail booting up.
ODELAY Supported = Check this only if the DDR3 is connected to the High Powered (HP) bank of your FPGA which supports ODELAY block. But for ALINX AX7103B FPGA board which has Artix-7, there is no ODELAY block.
Micron Simulation = This should only be checked during simulations, but since we want to implement UberDDR3 straight to hardware, make sure to not check this.
4. Run Connection Automation and select All Automation. Then, under uberddr3_axi_0, ensure that each clock is correctly mapped to its corresponding Clock Source. For example, as shown below, the i_ref_clk should be mapped to /clk_wiz/ref200_clk:
5. Add the AXI 1G/2.5G Ethernet Subsystem IP:
Run Block Automation and set the Physical Interface Selection to RGMII, as the Ethernet PHY chips on the AX7103 FPGA board utilize the RGMII interface. Next, select FIFO for the Connect AXI Streaming Interfaces to option:
Run Connection Automation and check All Automation:
6. Add the AXI Uartlite IP and AXI Timer IP, then run Connection Automation.
7. Now that we've added all the necessary IPs and peripherals, we need to manually edit some sections of the block design. Right-click on the DDR3 output port of uberddr3_axi_0 and select Make External. Change the name of this port to simply ddr3:
Next, rename the output port of the AXI Uartlite to uart:
Also, rename the output ports of the AXI 1G/2.5G Ethernet Subsystem to mdio, rgmii, and rgmii_rst_n:
As shown below, rename the input ports for the reset and differential clock to rst_n and sys:
The axi_ethernet_0_gtxclk requires a 100MHz input, so connect it to controller_clk, which generates the 100MHz signal:
Next, the i_rst_n input port of uberddr3_axi_0 should then be connected to peripheral_aresetn output port of Processor System Reset:
8. Open the microblaze_0_xlconcat block and set the Number of Ports to 4. This corresponds to the number of interrupts that MicroBlaze will manage:
The four interrupts that will be connected to microblaze_0_xlconcat are as follows:
axi_ethernet_0_fifo
axi_ethernet_0
axi_timer_0
axi_uartlite_0
The final block design should look like this:
If you’d like a clearer view, you can download the exported PDF file of the block design here:
9. Right click on the block design then Create HDL Wrapper:
Create a new constraint file, shown below are the constraints for AX7103B FPGA board:
Now, you can run Generate Bitsream. There should be no error or critical warning. Finally, export hardware as XSA file including bitstream.
II.II Implement Echo server in Vitis:
With the block design complete and the hardware XSA file exported from Vivado, we can now proceed to implement the program using Vitis:
1. Open Vitis from Vivado, choose your desired workspace, then Create Application Project.
Switch to Create a new platform from hardware (XSA) tab then browse for the XSA file which we just exported from Vivado earlier:
2. Provide your desired project application name. For the project template, choose lwIP Echo Server:
3. Once the directory and files are created, open the linker script lscript.ld located in the src folder. You’ll notice that it recognizes uberddr3_axi_0_ddr3_mem as a memory region. All sections are automatically mapped to UberDDR3, which is exactly what we want!
4. Build the project and launch the hardware. Click the play button to run the program. Connect the AX7103 FPGA board to your computer and set up the serial port in the Vitis Serial Terminal. The AXI Uartlite is configured to a baud rate of 9600 by default.
As shown in the serial terminal below, the Ethernet port was successfully detected! The board's IP address is 192.168.1.10 on port 7.
We also pinged this IP address (192.168.1.10) with 0% packet loss, as illustrated below!
Next, let’s test the actual echo server. Open the PuTTY application, set the IP address to 192.168.1.10, the port to 7, and choose Telnet as the Connection Type:
Switch to the Terminal settings, enable both Local echo and Local line editing, then click Open:
The terminal will open. Type anything then after you hit enter, it will be echoed back to you:
I made a quick video of the Ethernet Echo Server test, showing both the ping and PuTTY tests:
Congratulations! We've successfully set up a local echo server via Ethernet, powered by MicroBlaze with UberDDR3!
III. Conclusion
We’ve made significant progress since Part 1, where we integrated UberDDR3 into the IP Catalog and created a simple Hello World program with MicroBlaze and UberDDR3.
Here in Part 2, we took things to the next level by implementing a Dhrystone Test, comparing the performance and hardware utilization between UberDDR3 and MIG, with UberDDR3 coming out on top! Additionally, we successfully set up an Ethernet local echo server, showcasing the versatility and power of UberDDR3 for more complex, memory-hungry projects.
We hope you feel inspired to implement UberDDR3 in your next projects, unlocking new possibilities and enhancing your designs. If you have questions or issues, just hit me up here in LinkedIn or make an issue on the UberDDR3 repository.
That wraps up this post. Catch you in the next blog post!
Comments