Digilent Arty board and Linux - Part 2 - Linux Device Tree

We created a basic FPGA system capable to run Linux in the Part 1 around a Microblaze processor in a Xilinx Artix 7 FPGA (Arty evaluation board) and now it is time to build the Linux image.

For that task we are using Buildroot, an integrated tool to generate embedded Linux system including the generation of needed cross toolchain.

So the first thing we need to generate is the Linux Device Tree, which contains the hardware data needed by the booter and operative system to know how to deal with the created hardware. All memory map, existing buses, CPU details like cache configuration, interrupts or clock frequency, existing timers, UART modules details, etc.

  • To create our hardware we used IP cores from Xilinx, like AXI_Uartlite or the own Microblaze so we need to download the linux device tree for Xilinx, last version can be found in the following link. However I included the package file at the end containing used files.


    Extract device-tree-xlnx-master on Vivado project *.sdk subfolder.

  • On our Vivado project, go to File > Launch SDK. Once Eclipse is opened, go to Xilinx Tools > Repositories to include the new folder as a repository.
    Then click New ... and find the extracted folder.


  •  Go to File > New > Board Support Package and at the bottom, select device_tree. Default settings are ok to continue so click on Finish to create the project.
    A new window with the BSP settings is opened but with the default settings are enough to perform the example so click OK to go back to the Eclipse main view. In the future if you want to change the BSP settings you can double click to the .mss file and modify them.
    You can note the assigned drivers for each device:
    • axi_ethernetlite_0: emaclite
    • axi_timer_0: tmrctr
    • axi_uartlite_0: uartlite
    • microblaze_0_axi_intc: intc
    • microblaze_0_local_memory*: generic
    • mig_7series_0: mig_7series

It is time to create a .dts file containing the Linux Device Tree which will be included in the buildroot to build the kernel. We are going to merge the files "pl.dtsi" and "system.dts" created by the SDK.

  • Open the "pl.dtsi" and "system.dts" files. From the second one, copy the /dts-v1/; to the "pl.dtsi" file, previous to "/ {".
    In the same way, copy from "chosen {" to the closing "};" before the "cpus {" line. The result should look like the following screenshot.

Save the file as "artylinux.dts".

[PENDING] The MAC information for the ethernet interface needs to be located in the linux device tree in order to load the MAC address at the system start. I need to check where to put the information.


At this moment we have the Linux Device Tree for our created hardware, a file containing all needed information to compile and configure the booter and Linux kernel to be ran on our system.

The next step will be to compile the Linux kernel



[1] http://www.devicetree.org/specifications-pdf

[2] https://docs.numato.com/kb/neso-microblaze-linux-run-linux-neso-artix-7-fpga-module/

[3] https://events.linuxfoundation.org/sites/events/files/slides/petazzoni-device-tree-dummies.pdf


Digilent Arty board and Linux - Part 1 - FPGA system

Hello guys!

It have been a long time since my previous posts. I was really busy because I moved from my last job and I have been doing a lot of stuff for HAM radio. Moreover I changed the mail account password without reconfiguring the SMTP client and I lost a lot of mails from you. I tried to answer them all but months later... I am sorry.

Well, today I want to share one of my last goals: to run linux into a low-mid range FPGA and I succeeded some days ago. Let's go knowing more specific data:

I used an Arty evaluation board from Avnet/Digilent. It is based on a Xilinx Artix 7 35T FPGA, and mounts the following silicon:

  • Digilent USB to JTAG bridge and UART bridge
  • 16MB Quad-SPI flash
  • 256 MB DDR3L memory up to 667 MHz with 16bit data bus width
  • 10/100 Mbps Ethernet PHY
  • Some LED, switches, blah stuff
  • Vivado design license for the XC7A35T FPGA

with a cost of $99. I think that, in the world of FPGAs, it values more than its cost.

I have to say that they do not supply toooo much documentation, but Digilent provides needed IP cores to make it run easily and googling I could take enough information to make what I needed: to run Linux on a synthesized processor.

In the same way that Altera provides Nios II processor, Xilinx provides Microblaze, a 32-bit RISC soft-core processor which fully optimized, in the Artix-7 FPGA (-3) could yield up to 249 DMIPs @ 173 MHz or up to 431 DMIPs @ 299 MHz in the Virtex-7 Ultrascale (-3) family. Note that an ARM Cortex M4 MCU is moving around 225 DMIPs, with technology time difference of more than 5 years (only as a curiosity).


At this point, lot of the readers are thinking about the Xilinx Zynq-7000 SoCs, basically an Artix 7 FPGA with Dual ARM Cortex A9 processors in the same device. The Zynq is the next solution for better performance with not too much higher cost, replacing the soft-core with a hard-core processors, but I decided to make the effort with the Microblaze for two reasons: first one is that with Microblaze you have absolutely full control on the processor configuration and you learn a lot about core buses, the second one is that I shall use the Artix 7 FPGA on my project.

With no more waits, start knowing the steps and details:

  1. The first thing is to install the Vivado Design Suite. When finished it may look in this way:

  2. The first thing is to load the Digilent libraries for Vivado. You can download them from GitHub or directly from here.
    Extract the new/board_files folder and copy the folder in your Vivado installation folder, under */Xilinx/Vivado/2016.2/data/boards, you will see that there are other boards yet.
  3. Then create a new project, give the name you want (f.e. I gave "AA_ArtyLinuxTut") and select a RTL Project, and Do not specify sources at this time
    Now select the Boards tab and search for the Arty. Then finish the project creation.
  4.  At this time you will see the main Vivado design screen. At the left you can see the design flow from project management to FPGA deployment. As we have the project created, let's start with the IP integration. Click on Create Block Design and specify the design name, in my case system.

  5. In the left panel select the Board tab, you will see the different blocks that are included in the Arty board, like System Clock, Ethernet MII, DDR3 SDRAM or USB UART bridge. These blocks were created by Digilent based on existing IP Cores from Xilinx or another vendors.
    The first thing we include is the System Clock. Grab it from the list to the empty diagram on the right. Double click on the created block to edit the clock properties. Under Output Clocks tab, change the first clk_out1 from 100.00 MHz to 166.67 MHz. Then enable the second and third output clock and assign them 200.00 MHz and 25 MHz respectively. The first one will be for XXX, the second one for XXX and the last one for the Ethernet clock.
    Check the Active Low Reset Type.

  6. At this moment we have the system clock sources. Next step is to include the DDR3 SDRAM. Grab the DDR3 block to the diagram, two ports are created, clk_ref_i and sys_clk_i, delete them and connect clk_out1 to sys_clk_i and clk_out2 to clk_ref_i.
    At the top of the design diagram view, a green banner is shown, click on Run Connection Automation, select all options and click Ok. At this moment your system must look like this screenshot.

  7. Well, it is time to include the processor core. Right click on the Diagram view background and select Add IP..., search for Microblaze and include it.
    Double click on the Microblaze block and under Resources, Predefined Configurations, select Linux with MMU.
    It is time to Run Block Automation from the green banner and select the following configuration:
     - Local Memory: 32KB
     - Cache: 16KB
     - Enable "Interrupt Controller"
     - Clock Connection: ui_clk (83 MHz)

    The system is growing quickly, and should look like this:


  8. It is going well! Continue grabbing blocks. The next one is the USB UART block. Grab and modify it to change Baud Rate to 115200 under IP Configuration tab.
  9. Now drag the Ethernet MII.
  10. Do not stop! Right click on the diagram background > Add IP... and search for AXI Timer.
  11. Ok, Run Connection Automation from the magical green banner, check all again and click OK. Some obsolescence warnings will appear, ignore them.
  12. Ok, time to think a little. We now have three interrupt sources: UART, Ethernet and Timer. The interrupts controller block is the AXI Interrupt Controller and interrupt input is managed with the Concat block. Double click on Concat and select 3 ports.
    The first port will be the UART. Connect AXI UartLite Interrupt with the In0[0:0] of the Concat block.
    The second interrupt will be the Timer. Connect AXI Timer block Interrupt with the In1[0:0].
    The third is the Ethernet. Connect AXI EthernetLite ip2itc_irpt to In2[0:0] port of the Concat block.
  13. We need to create the input for the Ethernet Reference Clock. Right click on diagram and select Create Port...
    Port name: eth_ref_clk
    Direction: output
    Type: clock
    Connect this eth_ref_clk to clk_out3 on the Clocking Wizard block.
  14. As the diagram is getting messy, right click over the diagram and select Regenerate Layout. Tadaa, now it looks better.
    At this moment your design should look like this:

  15. Ok, we have finished creating the FPGA system. It was not difficult! Right click and select Validate Design. Vivado should tell you that the validation is successful, if not, review all your steps.
  16. Go on Block Design to Sources Tab, right click on system.bd block and click Create HDL Wrapper, Let Vivado manage wrapper and auto-update. It will create all Verilog code connecting your system.
  17. The only instruction that is missing is the eth_ref_clk. On the Sources tree, expand constraints and right click over constrs_1, then select Add Sources...Select Add or create constraints and Create File.
    File Type: XDC
    File Name: eth_ref_clk
    File Location: <Local to Project>
    Finish and double click on Constraints > constrs_1 > eth_ref_clk.xdc. Paste the following line into the file:
    set_property -dict { PACKAGE_PIN G18     IOSTANDARD LVCMOS33 } [get_ports { eth_ref_clk }];

    Save the file <Ctrl + S>

  18.  Now we are ready to generate th Bitstream file. Go to Flow Navigator and click on Generate Bitstream. As we did not executed the simulation, elaboration, systhesis nor implementation, Vivado will tell you that bitstream will be generated once synthesized and implemented. Click OK and wait some minutes. It may last from some minutes to an hour.
  19. Vivado will ask you to open the reports. You can analyze the results or simply click to cancel. Now we have implemented the system! Let's go exporting it.
  20. Go to File > Export > Export Hardware. Check Include Bitstream.

At this moment we have synthesized the Microblaze based system and it is ready to execute source code.
In the next post I explain how to generate the Linux Device Tree in order to configure and compile a clean Linux image ready to run on our Artix 7 FPGA. In the meantime you can try opening the Vivado SDK, create a Hello World application and try to launch it on our Microblaze processor. It is an easy process so you should be able to success in about 30 minutes. Do not forget to load the FPGA previous to Launch your program.

Enjoy it and do not stop learning!! See you in the next post!!



Syndicate content