Two slide decks presented at the embedded systems conference Boston
When it comes to creating our FPGA or SoC designs, it is inefficient and poor practice to not leverage IP cores and reuse of other design elements if they are available.
Before we start developing our own IP core, we should of course first check if such functions are available in the Vivado library or via Open Source repositories before we consider the need to create our own or purchase one from a third party supplier.
Of course, creating our own IP core establishes a library we can use to reduce the design time and hence cost of future projects.
However, often in our design we find ourselves implementing functions which have several IP cores connected in the same manner for example an image processing pipeline.
Each time we wish to implement this function within our design we need to add in and connect all the necessary IP cores. Again, this is inefficient, what is needed is a method of reusing these functions each time we want to instantiate it in this project and the next.
We can do this using hierarchical blocks.
Working with a block diagram design in Vivado we can create a reusable hierarchical block using the write_bd_tcl command. This command is one you may have used previously to output a TCL description of the block diagram so that it can be stored in a version control tool like Git.
Rather helpfully we can also use the same command to write out a description of a single hierarchical block within a block diagram. We can then use this TCL description to create multiple instances of the block at will across several projects.
So how do we do it?
Creating a hierarchical block within the block diagram is straight forward, simply right click on the block diagram canvas and select create hierarchy. If the IP cores we wish to include in this new block, already exist at the higher level all we then have to do is drag and drop them into the new hierarchical block. If not we can double click on the new hierarchical block which will open the block in a new window allowing us to add IP cores and connect them as desired.
Creation of the Hierarchical Block with the image processing chain
To create a TCL file description of this block we use the following command in the Vivado TCL console.
write_bd_tcl -force -hier_blks [get_bd_cells <hier block name>] <filename.tcl>
This command will write out a file which describes the hierarchical block contents and their connections. If we wish to add the block to an existing or new design, we do this by loading the file into Vivado, again we use the TCL Console.
Once the TCL file has been loaded, in the TCL Console window you will see notification of a new procedure which can be called to create a new instance of the block in the project.
Calling this procedure results in a new hierarchical block being added to your design. For this example using the image processing chain above, I used the following command to add a second image processing block.
create_hier_cell_IPC / NEW_IPC
Examining the new block against the initial block demonstrates the contents are identical as we would expect.
We can now use this created TCL file across several designs where we want to create a image processing chain saving time. If we want to ensure it is has the maximum reuse potential, we can use the -no_ip_version option in the write_bd_tcl command to prevent the IP version from being included within the file. This makes the script more versatile with different versions of Vivado.
One final point having created the TCL file it is a good idea to enter it into a version control tool as we would with any other design element.
- Ensure the project your loading the script into can see all of the IP cores used in the script. Make sure you have all the repositories added in the Vivado project.
- If you change the module and over write the generated TCL description. For the changes to take effect in your project you must reload it in to Vivado and then re instantiate it.
- When you create the TCL description make sure you know where the file will be created by running a pwd command first and if necessary setting the working path to a more friendly location.
- Simplify the interfacing of the block by using custom interface definitions within Vivado and the IP Packager.
MicroZed Chronicles on GitHub
Want a Book
One thing that is always important for engineers, is the need for us to deliver our projects on quality, schedule and budget. When it comes to developing embedded systems there are a number of lessons, learnt by embedded system developers over the years which can be used to ensure your embedded system achieves these. Let us explore some of the most important lessons learned in developing these.
Completing the RTL design is one part of getting
your FPGA design production-ready.
The next challenge is to ensure the design
meets its timing and performance requirements
in the silicon. To do this, you will often need to
define both timing and placement constraints.
Let’s take a look at how to create and use both
of these types of constraints when designing systems
around Xilinx® FPGAs and SoCs
Sometimes despite the simulation we have performed upon our design we still have issues with the design on the hardware. One way we can debug in the hardware is to use a ILA within our hardware design, this gives us the ability to monitor either a number of AXI interfaces or discrete inputs.
Adding in an AXI monitor on the AXI interface to the XADC we are currently using in our example we enable us to monitor the transactions. In this case just such that we can examine them however in other instances it may be necessary due to design or integration issues.
We can add in the ILA into our design from the Integration library in our block diagram.
Insertion of the ILA into the Design
By default, the ILA is configured to monitor a AXI interface however, we can change its settings by double clicking on the ILA block and customising as required. We can add in trigger ports, capture control and comparators to trigger on specific patterns in the data stream. For this example, I am going to keep it fairly simple to show the flow and then we can look at more advanced aspects once this is understood.
Customising the ILA
With the ILA inserted into the design the next stage is to reset the generated outputs and then re generate these such that we can implement the design. Once the design is implemented we can then programme the device using the hardware manager, it is via the hardware manager that we can also examine the contents of the interfaces we wished to examine.
Using the hardware manager, we should connect to our Arty target, the next step is to programme the FPGA and initialise the logic analyser. To achieve this we need both the bit file and the definition of the debug nets we wanted to examine in the Vivado block diagram, you will see this as the ltx file within the projects runs / implementation directory beside the bit file.
Identifying the ltx file
Configuring the device and debug profile.
Once these files have been configured we will see the screen below open up in the hardware manager which provides the interface we can use to configure the triggering, capture mode and arm the ILA core.
Once we have configured the core as we wish, we can examine the waveform in the waveform viewer below.
ILA Configuration and control scheme in Hardware Manager
With the simple flow explained we can, in the next blog look at how we can use more advanced features of the ILA.
One of the most common uses of the XADC is for health monitoring of the FPGA and the wider system to that mind the XADC has a number of useful features which can be used.
- Trigger and Reset Threshold Alarm registers for the Internal voltages and temperature parameters
- Over Temp Monitoring – Maximum junction operating temperature allowable for the device – Auto shut down is possible.
- Maximum and Minimum values – Registers which contain the lowest and highest sampled values for each of the voltages and device temperature.
These three elements make for a very useful health monitoring system, of course the alarms and the over temperature must be correctly configured and enabled first. This can be achieved in one of two ways, either via the XADC wizard within Vivado or via our software application.
There are seven possible alarms we can configure on the XADC, however we cannot use all of them on the Artix Silicon as some alarms as dedicated to the Zynq (Alarm 6 Vccddro, Alarm 5 Vccpaux and Alarm 4 Vccpint). There is also an eighth alarm bit which is the logical OR of the seven alarm bits and acts as an overall alarm.
We can see if an alarm has occurred via either the Alarm Status Output Register or configure an interrupt to occur should an alarm condition occur such that it can be immediately dealt with.
These trigger and reset values allow us to define values which align with our worst case analysis of supply voltages and junction temperature, ensuring we can protect the system properly.
Each alarm also has an associated output which can be used in the wider system either to indicate via a LED a issue has occurred or to take further action e.g. graceful system degradation.
The over temperature alarm is slightly different in that it can be configured to trigger an automatic shutdown of the device. To set automatic shut down the four LSB’s of the over temperature register must be set high. Doing this means that 10 ms after the trigger level is reached a shut down occurs. This prevents re -configuration of the device until the reset level is reached.
It is intended that the temperature alarm is used to act as a pre-warning that the temperature has exceed what the design has calculated as its maximum. This way the system can take action to prevent the shut down e.g. turning on fans, reducing processing etc.
While the maximum and minimum registers provide the system with a simple methodology of quickly and easily checking the worst case values as currently observed by the system during its period of operation. These registers can also be of good use in system commissioning to record supply voltages and temperatures across worst case environmental conditions for example.
There is also one last issue which must be addressed when using the XADC on the Arty board and that is we need to correctly set up the board to use the internal VRefp. Failure to do this results in a inaccurate conversions. The Arty board is configured such that you can use either the internal or external reference.
We can ensure the internal reference is used by grounding the XADCVREF input, as such the internal reference will be used. This can be confirmed by reading the flag register which also helpfully contains information on any alarms as well
With the XADC configured to correctly monitor the internal signals with suitable alarm levels we can look at how we can use the XADC to receive analogue signals from the real world
The Arty board is the next generation of the very useful LX9 MicroBoard however, it takes account of advances in devices and interfacing. I ordered mine just before I recently flew to Japan, and it was waiting for me when I returned.
The Arty is marketed as the perfect development platform for MicroBlaze applications as such when I opened my Arty the first thing I wanted to do was a new build from scratch of a MicroBlaze system. This way I could really understand the ease (or not) with which it could be developed, in the end it was very easy to create both the hardware application and create the simple software to say hello world.
To get MicroBlaze up and running on my Arty I did the following
- Download and install the most update version of Vivado (remember to install the Vivado Design Edition)
- Redeem the license for the Vivado SW which comes with the Arty
- Download the Arty board definitions
- Create the hardware definition within a new Vivado project
- Build the hardware definition and export it to SDK
- Create out SW application – This needs Hardware Definition, Board Support Package and Application SW.
While it may seem daunting these stages can be achieved quickly, also I am not going to talk you through how to do the first two points as they are very straight forward.
Which brings us to downloading the board definitions, these are available at the following link https://reference.digilentinc.com/vivado:boardfiles Once you have downloaded the board files you need to extract the Arty board definitions and store it within your Vivado installation <VIVADO DIRECTORY>/data/boards/ on my system the path is C:\Xilinx\Vivado\2015.3\data\boards\board_files
Within the arty directory you will then see the board definition XML and most helpfully a mig.prj this is the settings for the memory interface generator for if we wish to use the DDR on the arty (and we will of course).
This enables us to create a new project and select the Arty board, which is our next step
Once we have the project created the next step is to create the MicroBlaze system, to do this we need to create a block diagram within which we can create our system. You can create a block diagram by selecting Create Block Diagram option under the Flow Navigator on the left of Vivado
Once the block diagram is open we need to add the following things to it
- MicroBlaze System – See end of blog for customisation
- Memory Interface Generator – This uses the arty settings so it is just a case of scrolling through and generating the options
- AXI UART lite – for communication externally – double click on it to set your RS232 options the default is 9600 no parity one stop bit
- AXI Timer
- AXI Interrupt Controller – We need a concatenate block to drive the interrupt from the timer and the AXI UART lite
- AXI BRAM Controller and BRAM for the AXI Data and Instruction Cache
- Clocking wizard to output a 166.667 MHz Clock and a 200 MHz Clock
- MicroBlaze Debug Module
- AXI Peripheral Interconnect to connect to the timer and UART
- AXI Memory Interconnect to connect to the MIG (DDR) and the AXI BRAM controller
- Processor Reset System
The clocking of the MicroBlaze and all AXI peripherals should use the output clock from the MIG (ui_clk) while the MCM reset from the MIG block should be fed back to the processor reset system DCM input, the ui_clk_rst goes to the ext_reset_in on the reset block.
The clock wizard outputs connects as below
The rest of the connections are pretty straight forward AXI connections, the only difference is the need to add in a MicroBlaze Local DLMB and ILMB memory we can use the Run Block Automation Option (MicroBlaze) available on top of the block diagram editor.
When it is all complete your diagram will look like the below
The one thing we have not done by this point is to connect up the IO on the design to those on the board. We can do this by selecting on the board tab within the block diagram
We can then right click on a signal we wish to use and select Connect Board Component as below
It is then just a simple case of selecting the existing IP to connect it to
Do this for the following
- Sys_clk – 100 MHz clock on the Arty
- DDR3_SDRAM – the DDR on the arty
- USB_UART – How we will say hello world
- Reset – Reset input
This saves us from having to write a XDC file with the pin locations needed to ensure we use the correct IO with the board.
With this completed we can validate our design and we should not get any warnings – if you have any address issues see he Address Editor tab mine looked like below when it was validated OK
Once it has validated OK you are in a position that you can build the hardware, and export the hardware definition to SDK.
I will post another blog tomorrow on how to get the SDK side of things up and running but below is the result
Below are the MicroBlaze customisations
Because of its unique mix of ARM processing
clout and FPGA logic in a single device, the
Zynq™-7000 All Programmable SoC requires a
twofold configuration process, one that takes into
account both the processor system and the programmable
logic. Engineers will find that the configuration
sequence differs slightly from that of traditional
Xilinx® FPGAs. Nevertheless, the methodology is
familiar and it’s not at all difficult to generate a boot
image and program the configuration memory.
Where standard FPGA configuration practices normally
require only the FPGA bit file, you will need to
add a second type of configuration file to get the maximum
benefit from your Zynq SoC: the SW Executable
and Linakble Format (ELF) file. The FPGA bit file
defines the behavior of the programmable logic section
of your design, while ELF file is the software program
that the processing system will execute.
So let’s have a look at how to implement a baremetal
(no operating system) software application on
your Zynq SoC.