====== Nexys 4 DDR - Getting Started with Microblaze Servers ====== Warning! This guide is out of date. While it should still work as written in the original versions of the tools it was written for, users have reported that resulting designs are not functional in recent versions - 2022.2 being the latest at time of writing. {{ :reference:programmable-logic:nexys-4-ddr:nexys-4-ddr-0.png?direct |}} ===== Overview ===== This guide will provide a step by step walk-through of creating a Microblaze based hardware design using the Vivado IP Integrator that will build over the [[nexys4-ddr:gsmb|Getting Started with Microblaze]] guide by making use of the on-board Ethernet port and GPIOs for the Nexys 4 DDR FPGA board. At the end of this tutorial you will have a comprehensive hardware design for Nexys4 DDR that makes use of various Hardware ports on the Nexys 4 DDR which are managed by the Microblaze Softcore Processor block. ----- ===== Prerequisites ===== === Hardware === * **Digilent Nexys 4 DDR FPGA Board** * **Micro USB Cable** === Software === * **Xilinx Vivado 2015.X with the SDK package** === Board Support Files === * **Board Support Files** * These files will describe GPIO interfaces on your board and make it easier to select your FPGA board and add GPIO IP blocks. * Follow this Wiki guide ([[vivado:boardfiles|Vivado Board Files for Digilent 7-Series FPGA Boards]]) on how to install Board Support Files for Vivado. === Important! === Xilinx deprecated the Ethernet PHY MII to Reduced MII (MII2RMII) after Vivado version 2019.1 without a direct replacement. This core can still potentially be used in newer versions by obtaining a copy of the IP's sources from an installation of Vivado 2019.1 or earlier. You can include it in 2019.2 onwards by including the IP sources as you would a regular IP repository. [[https://support.xilinx.com/s/question/0D52E00006hpK3cSAE/replacement-for-the-discontinued-mii-to-rmii-ip-core|This thread]], from the Xilinx support forum, has additional information on the workaround. ----- ===== Introduction ===== Microblaze is a soft IP core from Xilinx that will implement a microprocessor entirely within the Xilinx FPGA general purpose memory and logic fabric. For this tutorial, we are going to add Ethernet functionality and create an echo server. ---- ===== General Design Flow ===== I. Vivado * Open Vivado and select Nexys 4 DDR board * Create an new Vivado Project * Create empty block design workspace inside the new project * Add required IP blocks using the IP integrator tool and build Hardware Design * Validate and save block design * Create HDL system wrapper * Run design Synthesis and Implementation * Generate Bit File * Export Hardware Design including the generated bit stream file to SDK tool * Launch SDK Now the Hardware design is exported to the SDK tool. The Vivado to SDK hand-off is done internally through Vivado. We will use SDK to create a Software application that will use the customized board interface data and FPGA hardware configuration by importing the hardware design information from Vivado. II. SDK * Create new application project and select default Hello World template * Program FPGA * Run configuration by selecting the correct UART COM Port and Baud Rate ----- ===== Tutorial ===== ==== 1. Creating a New Project ==== >1.1) Open up Vivado and click **Create New Project** to open Vivado's New Project wizard. > >{{:basys3:basys3_screen_shot_2015-6-10_1.png?direct&500|}} >1.2) A new window will open up, click **Next** and you'll see the screen below. Name your project (no spaces!) and choose your project saving directory before clicking **Next**. Underscores are a good substitute for empty spaces. > >{{:basys3:basys3_screen_shot_2015-6-10_2.png?direct&500|}} >1.3) We will be building this project from the ground up and adding our own sources so we will want to create an RTL project. Select **RTL Project** and leave the **Do not specify sources** box unchecked. Click **Next**. > >{{:basys3:basys3_screen_shot_2015-6-10_3.png?direct&500|}} >1.4) If you have followed the Board Support File Wiki guide then click next and select **Boards**. From the filter options make required selections for Vendor, Display Name and Board Revision. **Nexys 4 DDR** should be displayed in the selection list. A mismatch in selecting the correct board name will cause errors. > >{{:arty:1.jpg?direct&500|}} >1.5) Click **Next**, a summary of the new project design sources and target device is displayed. Click **Finish**. > >{{:vivado:mig_3.jpg?direct&500|}} At this point you have successfully created a project that will properly communicate with the Nexys 4 DDR. ---- ==== 2. Creating New Block Design ==== >2.1) This is the main project window where you can create a IP based block design or add RTL based design sources. The flow navigator panel on the left provides multiple options on how to create a hardware design, perform simulation, run synthesis and implementation and generate a bit file. You can also program the board directly from Vivado with the generated bit file for an RTL project using the Hardware Manager. For our design, we will use the IP Integrator to create a new block design. > >{{:vivado:mig_4.jpg?direct&500|}} >2.2) On the left you should see the Flow Navigator. Select **Create Block Design** under the IP Integrator. Give a name to your design without any empty spaces. > >{{:vivado:mig_5.jpg?direct&500|}} === Add the Microblaze Core: === >2.3) An empty design workspace is created where you can add IP blocks. Click on the {{:genesys2:addip.jpg?nolink|}} **Add IP** button. This should open a catalog of pre-built IP blocks from Xilinx IP repository. Search for "Microblaze" and double click on it to add the IP block to your empty design. > >{{:vivado:mig_6.jpg?direct&500|}} >2.4) This is the Xilinx Microblaze IP block. When a new IP block is added the user can customize the block properties by either clicking on the **Run Block Automation** message prompt or by double clicking on the block itself. > >{{:vivado:mig_7.jpg?direct&500|}} > >2.5) Select **Run Block Automation** and a customization assistant window will open with default settings. Set up like picture below. >{{:learn:programmable-logic:tutorials:nexys-4-ddr-getting-started-with-microblaze-servers:esc_nexys4ddr.jpg?direct&500|}} > >2.6) Running the block automation will auto-generate a set of additional IP blocks which will be added to our hardware design automatically based on the options selected in the previous step. **Do not click on Run Connection Automation yet.** > >{{:nexys4-ddr:mig_10-2.png?direct&500|}} === Adding the Necessary Output Clocks: === >2.7) Double click on the **Clock Wizard** (clk_wiz_1) IP block. > >{{:vivado:mig_12.jpg?direct&500|}} >2.8) Change **CLK_IN1** to use "sys clock", and **EXT_RESET_IN** to use "reset" as shown below and click **OK**. This will customize the block with our new user settings. > >{{:nexys4-ddr:server_4.jpg?direct&500|}} >2.9) Select the **Output Clocks** tab. > >{{:vivado:mig_14.jpg?direct&500|}} >2.10) Enable **clk_out2**, and **clk_out3**. Set **clk_out2** to "200.0" MHz, **clk_out3** to "50.0" MHz, and set **Reset Type** as //Active Low//. The left panel shows a GUI representation of the block and its internal settings. Observe that the reset pin will now read as //resetn//. Once finished click **OK**. > >{{:nexys4-ddr:server_5.jpg?direct&500|}} ---- ==== 3. Adding the IP Cores ==== >3.1) We will now add all of the necessary IP blocks to our project. There are 4 cores we will add: * Memory Interface Generator * Ethernet PHY MII to Reduced MII * AXI Uartlite * AXI EthernetLite * AXI Timer >3.2) Add all of these to your design, one at a time, using the {{:genesys2:addip.jpg?nolink|}} **Add IP** button. Once they are all added, you should see the four blocks shown below. > >{{:nexys4-ddr:server_7.jpg?direct&500|}} ---- ==== 4. Configuring and Routing the IP Cores ==== >4.1) Click **Run Block Automation** and run it for the mig_7series_0 block. > >{{:nexys4-ddr:server_8.jpg?direct&500|}} > >When the MIG block automation is run, you will see this specific error message [BD 41-1273]. You can ignore this for now. It will not affect your design in any way. The MIG block will be configured as per the board support files that have been downloaded for the Nexys 4 DDR. Click **OK** to dismiss this message. > >{{:nexys4-ddr:mig_27-2.jpg?direct&500|}} >4.2) On the //AXI EthernetLite block//, connect the **MII output** to the **MII input** on the //Ethernet PHY MII to Reduced MII block//. To do this, hover over the blue rectangle next to MII+ until you see a pencil cursor. Click and drag this over to the +MII input of the other block and release. > >{{:nexys4-ddr:server_9.jpg?direct&500|}} >4.2) Route **clk_out2** and **clk_out3** on your //Clocking Wizard// block to **sys_clk_i** on the //Memory Interface Generator// and **ref_clk** on the //Ethernet PHY MII to Reduced MII// block respectively. > >{{:nexys4-ddr:server_10.jpg?direct&500|}} >4.3) Click **Run Connection Automation**. Un-check the //microblaze_0// check-box and click **OK**. > >{{:arty:6.jpg?direct&500|}} >4.4) Click **Regenerate Layout** (circled in blue below), and your block design should look like this: > >{{:arty:7.jpg?direct&500|)}} >4.5) Route **interrupt** on the //AXI Timer// block to **In0[0:0]** on the //Concat// block. Next route **ip2intc_irpt** on the //AXI EthernetLite// block to **In1[0:0]** on the //Concat// block. > >{{:nexys4-ddr:server_13.jpg?direct&500|}} >4.6) Connect **resetn** on the //Clocking Wizard// block to the **reset** pin. > >{{:arty:server_14.png?direct&500|}} >4.7) Right click somewhere in the background (white space) of your design and click **Create Port...**, or use the shortcut, Ctrl-K. Name this port "eth_ref_clk" and change the options to the one in the picture below. Click **OK** once finished. > >{{:nexys4-ddr:server_15.jpg?direct&500|}} >4.8) Connect this **eth_ref_clk** pin to **ref_clk** on the //Ethernet PHY MII to Reducted MII// block. > >{{:nexys4-ddr:server_16.jpg?direct&400|}} >4.9) Right click on the blue striped rectangle next to the **DDR2+** bus on the //Memory Interface Generator// block and click **Make External**. > >{{:nexys4-ddr:ddr2_ext.png?direct&500|}} >4.10) Clicking **Regenerate Layout** again will result in your final block design layout for this project. > >{{:arty:10.jpg?direct&500|}} >4.11) We must now connect the eth_ref_clk pin to the correct pin on the FPGA by creating an XDC file. Under the //Design// window, select the **Sources** tab. Expand the //contraints// folder, right click on //constr// and click **Add Sources...** > >{{:nexys4-ddr:server_19.jpg?direct&500|}} >4.12) Select **Add or create constraints** and click **Next**. > >{{:nexys4-ddr:server_20.jpg?direct&500|}} >4.13) Click **Create File...**, name your new contraints file and click **OK** and then **Finish**. > >{{:nexys4-ddr:server_21.jpg?direct&500|}} >4.14) Open your new constraints file and paste the following line of code in it: > set_property -dict { PACKAGE_PIN D5 IOSTANDARD LVCMOS33 } [get_ports { eth_ref_clk }]; # Sch=eth_ref_clk Save the xdc file when you are finished. >4.15) Now, right click on your design_1 block diagram and click **Create HDL Wrapper**. When the window pops up, select the **Let Vivado manage wrapper and auto-update** bullet and click **OK**. > >{{:nexys4-ddr:server_22.jpg?direct&500|}} >4.16) Click **Generate Bitstream** at the top of the work space. This process will take a while. > >{{:nexys4-ddr:server_23.jpg?direct&500|}} ---- ==== 5. Exporting Hardware Design to SDK ==== >5.1) On the top left corner of the window, from the tool bar click on **File->Export Hardware**. Make sure the generated bitstream is included by checking the box. This will export the hardware design with system wrapper for the Software Development Tool - Vivado SDK. > >**There is currently a bug where the //download.bit// file is not generated for the Nexys 4 DDR board. To work around this, click File->Export->Export Bitstream File... then navigate to project/project.sdk/design_1_wrapper_hw_platform_0 and export a new bit file called "download"** > >{{:nexys4-ddr:server_24.jpg?direct&500|}} ---- ==== 6. Launching SDK ==== >6.1) Go to **File->Launch SDK** and click **OK**. The SDK file created local to the Vivado design project location will be launched. The hand-off to SDK from Vivado is complete. > >{{:vivado:mig_45.jpg?direct&500|}} ---- ==== 7. Inside SDK for Vivado ==== >7.1) A new window for SDK will open. The HW design specification and included IP blocks are displayed in the //system.hdf// file. SDK tool is independent of Vivado, i.e. from this point, you can create your SW project in C/C++ on top of the exported HW design. If necessary, you can also launch SDK directly from the SDK folder created in the main Vivado Project directory. > >Now, if you need to go back to Vivado and make changes to the HW design, then it is recommended to close the SDK window and make the required HW design edits in Vivado. After this you must follow the sequence of creating a new HDL wrapper, save design and bit file generation. This new bit file and system wrapper must then be exported to SDK. > >Since we do not have any HW design edits at this point, we will proceed with creating a software application to run an echo server. > >{{:vivado:mig_46.jpg?direct&500|}} ---- ==== 8. Creating New Application Project in SDK ==== >8.1) Go to **File->New->Application Project** in the main toolbar. A new project window will pop up. Give your SDK project a name that has no empty spaces as shown below. Make sure the **Target Hardware** is the correct hardware design. In our case, it will be //design_1_wrapper_hw_platform_0//. > >If for example, you also have another hardware design in the //Project Explorer// window, then you will also see this design name in the Target Hardware drop down selection list. > >Since we only have one hardware design **design_1_wrapper_hw_platform_0** this will be our target hardware. Select **Create New** under **Board Support Package**. The tool will automatically populate the **Board Support Package** name to match with the give project name. Click **Next**. > >{{:nexys4-ddr:server_25.jpg?direct&500|}} > >8.2) Select **IwIP Echo Server** under the list of available templates and click **Finish**. > >{{:nexys4-ddr:server_26.jpg?direct&500|}} >8.3) After completing the previous step, you will see two new folders in the //Project Explorer// panel. **echo_server** which contains all the binaries, .C and .H (Header) files, and **echo_server_bsp** which is the board support folder. **echo_server** is our main working source folder. This also contains an important file shown here in the src folder called //lscript.ld//. This is a Xilinx auto generated linker script file. Double click on this file to open. ---- ==== 9. Verify Linker Script File for Memory Region Mapping ==== >9.1) In the linker script, take a look at the **Section to Memory Region Mapping** box. If you did the //Make DDR2 External// step then the //target memory region// column **must** read **mig_7series_0**. >9.2) Scroll down to check if this applies to all rows. If for any region it does not say **mig_7series_0**, then click on the row under the **Memory Region** column and select **mig_7series_0**. > >{{:nexys4-ddr:server_28.jpg?direct&500|}} ---- ==== 10. Setting PHY Link Speed ==== >10.1) Open the **system.mss** file within the //echo_server_bsp// folder and click **Modify this BSP's Settings**. > >{{:nexys4-ddr:server_30.jpg?direct&500|}} >10.2) Once in **Board Support Package Settings** select **Overview->standalone->lwip141**. The configuration table for the lwip141 library should now be visible on the right. Navigate to **temac_adapter_options->phy_link_speed**. Here you will need to change **CONFIG_LINKSPEED_AUTODETECT** to **CONFIG_LINKSPEED100** so that it looks like the picture below. > >{{:arty:server_31.png?direct&500|}} ----- ==== 11. Programming FPGA with Bit File ==== >11.1) Make sure that the Nexys 4 DDR is turned on and connected to the host PC via micro USB cable. On the main toolbar, click **Xilinx Tools->Program FPGA** >Make sure that the //Hardware Platform// is selected as **design_1_wrapper_hw_platform_0**. > >In the software configuration box, under //ELF File to Initialize in Block RAM// column, the row option must read **bootloop**. If not, click on the row and select **bootloop**. > >Now click on Program. >{{:nexys4-ddr:server_29.jpg?direct&500|}} ---- ==== 12. Setting up the SDK Serial Console and Running the Server ==== >12.1) Right click on the //echo_server// project folder and select **Run As->Run Configurations** > >{{:nexys4-ddr:server_32.jpg?direct&500|}} >12.2) Go to the //STDIO Connection// tab and check the //Connect STDIO to Console// check-box. Click **Apply**, then click **Run**. > >{{:nexys4-ddr:server_33.jpg?direct&500|}} ---- ==== 13. Running the Server ==== >13.1) In the console window at the bottom of the screen the details of the connection will be displayed. > >{{:nexys4-ddr:server_34.jpg?direct&500|}} ---- ==== 14. Testing the Server with Tera Term ==== >14.1) Connect your PC to your Nexys 4 DDR using an Ethernet cable. **If using a router, watch the UART console to find out the IP of the Nexys 4 DDR echo server, and connect to that IP address. Setting up the connection as static is unnecessary.** >14.2) In order to connect to the echo server directly from your computer, you must set up your Ethernet connection with a static IP address. To do this: >14.2.1) Right click your internet connection and click **Open Network and Sharing Center**. > >{{:nexys4-ddr:server_35.jpg?direct&500|}} >14.2.2) Find the Ethernet Connection to your Nexys 4 DDR. It should be an unidentified network. Click **Local Area Connection**. > >{{:nexys4-ddr:server_36.jpg?direct&500|}} >14.2.3) Click **Properties**. > >{{:nexys4-ddr:server_37.jpg?direct&500|}} >14.2.4) Select **Internet Protocol Version 4 (TCP/IPv4)** and click **Properties**. > >{{:nexys4-ddr:server_38.jpg?direct&500|}} >14.2.5) Click the **Use the following IP address:** bullet and type in an IP address "192.168.1.XX", where XX is a value between 2 and 255, but not 10. **This IP must not be the same as another already on your network**. Make sure to click within the //Subnet mask// field to get the 255.255.255.0 mask to autofill. Click **Ok** and you will have a static IP address. > >{{:nexys4-ddr:server_39.jpg?direct&500|}} >14.3) Open Tera Term and type in the following info and click **Ok**. > >{{:nexys4-ddr:server_40.jpg?direct&500|}} >14.4) Type anything into the console and press your keyboard's Enter key. The echo server will echo back your input and display it in the console. > >//You can go to Setup->Terminal and change the settings below for a more traditional echo server format// > >{{:nexys4-ddr:11.jpg?direct&500|}} {{tag>learn programmable-logic tutorial nexys-4-ddr microblaze}}