In one of my previous project posts, I covered how to create a base hardware design for running bare-metal/no-OS applications in Vivado for the Artix-7 based Arty-A7 FPGA development board. As mentioned in that post, the Artix-7 FPGA on the Arty-A7 board is purely FPGA logic and does not have a physical processor built into it like its Zynq counterparts in the AMD-Xilinx 7series lineup. Thus, to get the functionality of a processor on the Artix-7, users need to instantiate a soft-core processor such as the MicroBlaze from AMD-Xilinx's IP catalog.
A full OS requires a bit more resource-wise from a processor than a bare-metal application does, therefore the hardware design in Vivado for my Arty-A7 is going to look different as compared to my previous post.
Create Vivado ProjectYou can either start from the existing Vivado project from my previous post and modify it, or create a new project targeting whichever of the two Arty-A7 variants being used (the smaller A7-35 or the larger A7-100).
For this project post, I started with a new project because I was curious to run a power analysis on each (using the power reporting tools from the Implemented Design in Vivado).
Block DesignFirst things first as always, create a block design using the Create Block Design option from the Flow Navigator window.
Add the MicroBlaze soft processor to the block design and double-click on it to open its configuration window.
On page one, select the configuration for Linux with memory management unit (MMU):
Leave the default options set for pages two and three. Then on page four, increase the instruction/data cache size to 64KB.
Don't forget to update this also in the Address Editor:
Skip pages 5-6, leaving the default options set. Finally on page 7, enable the option for Peripheral AXI Instruction Interface.
Click OK to close the MicroBlaze configuration window. The option to run Block Automation will appear, but do not run it yet.
Switch to the Board tab, right-click on the peripheral option for DDR3 SRAM and select the option to connect the board peripheral. Select mig_ddr_interface as the IP for connecting the DDR3 SRAM.
Also connect System Clock using the Clocking Wizard IP (clk_wiz).
Double-click on the Clocking Wizard IP to open its configuration window and change clk_out1 to 166.66667MHz. Then enable clk_out2 and change it to 200.000MHz. Also change reset from active high to active low.
Connect System Reset using the Board tab and select the existing Clocking Wizard to connect it to (clk_wiz_0).
At this point the option for Connection Automation has appeared for the mig_7series_0 IP for the DDR3:
Once completed, delete the external ports created for sys_clk_i and clk_ref_i on the mig_7series_0 IP. Then connect sys_clk_i to clk_out1 (166.66667MHz) of the Clocking Wizard and clk_ref_i to clk_out2 (200.000MHz).
At this point, run Block Automation for MicroBlaze. I learned the hard way that running Block Automation prior to configuring the DDR3 clock structure causes auto-connect hell. The rest of the design needs to be driven from the output clock of the MIG memory controller (ui_clk). However if the input clocks to it are not properly configured manually before running Block Automation, Vivado will auto-generate a separate and independent clock structure which will cause timing errors and meta-stability in Linux later as it attempts to access the DDR.
In the options window for Block Automation, select the option to add an Interrupt Controller.
After Block Automation completes, run Connection Automation for M_AXI_IP on MicroBlaze. Select microblaze_0_axi_intc as the Slave Interface of the microblaze_0_axi_periph Bridge IP.
After Connection Automation completes, validate the block design to check clocks/resets are properly connected.
Use the Board tab to connect the following peripherals (using the IP blocks in parenthesis):
- Ethernet MII (AXI EthernetLite)
- Quad SPI FLash (AXI Quad SPI)
- 4 LEDs (AXI GPIO)
- 4 Push Buttons (Ch2 of 4 LEDs AXI GPIO)
- Shield Pins 0 thru 19 (AXI GPIO)
- Shield Pins 26 thru 41 (Ch2 of Shield Pins 0 thru 19 AXI GPIO)
- SPI connector J6 (AXI Quad SPI)
- USB Uart (AXI UartLite)
Run Connection Automation for all of the IPs added, verifying that microblaze_0_axi_periph is the Bridge IP for all. Also make sure the ext_spi_clk for both AXI Quad SPI IPs are connected to ui_clk from mig_7series_0.
Add an AXI Timer and run the Connection Automation that appears after adding it to the block design (learned the hard way, Linux won't boot without this).
As mentioned previously, make sure the size of the instruction and data caches for the MicroBlaze in the Address Editor tab of the Block Design match the Linux configuration set, which is 64KB in this case.
Change the number of inputs on the concat IP connected to the input of the interrupt controller (microblaze_0_xlconcat) from 2 to 6. Connect the interrupt outputs from the peripherals to microblaze_0_xlconcat in the following order from 0 to 5:
- In0 - AXI Timer
- In1 - AXI UartLite
- In2 - AXI EthernetLite
- In3 - AXI Quad SPI (QSPI)
- In4 - AXI GPIO (Shield Pins)
- In5 - AXI Quad SPI (J6 SPI)
Validate and save the design, then generate the block design using the Generate Block Design option from the Flow Navigator window.
Create HDL WrapperIn order to instantiate the block design in the project, a top-level HDL wrapper needs to be created.
Switch back to the Sources tab from the Board tab, right-click on the block design file, and select the option to Create HDL Wrapper...
When prompted, select the option to allow Vivado to auto-manage it.
The HDL file will be generate in whichever language (VHDL or Verilog) is set in the project's settings. The default language setting in Vivado is Verilog.
Generate BitstreamAt this point, the hardware design is complete so we're ready to generate a bitstream for it.
If you select Generate Bitstream directly from the Flow Navigator, Vivado will automatically run synthesis and implementation first which saves a few button clicks. Otherwise you can run synthesis, implementation, and generate a bitstream as separate steps.
Export HardwareFinally the hardware design needs to be packaged and exported into an XSA file to pull it into PetaLinux and an generate the embedding Linux image that will be running on it.
Select File > Export > Export Hardware...:
Step through the Export Wizard, and select the option to include the bitstream in the exported design on the second page.
As with the bare-metal hardware design, you can specify any desired output directory you prefer. I like to leave it set to the default location of the top level directory of the Vivado project.
At this point, we're ready to switch over to PetaLinux to build the image for the Arty-A7.
Comments