Let's take a look at an example design that covers several common needs the typical MicroBlaze user might have, including how to access DDR memory, how to use the peripherals in the PS' IOP, how to pass blocks of data between the MicroBlaze and the PS, and how to synchronize events between the MicroBlaze and the PS. Figure 4 shows specific techniques to address each of these issues (labeled 1-4, respectively).
Figure 4. Block diagram of example hardware design; the numbers represent (1) ways to access DDR memory; (2) use of the peripherals in the PS’ IOP; (3) how to pass blocks of data between the MicroBlaze and the PS; and (4) how to synchronize events between the MicroBlaze and the PS.
The easiest way to access the DDR memory is to connect through one or more of the four high-performance (HP) AXI interfaces (top right section of the diagram). Four 64-bit-wide ports are accessible to the programmable logic. You must first enable a port; then you can connect an AXI to it. The MicroBlaze utilizes the AXI4-Lite interface, whereas the HP ports are expecting full AXI4 connections. Fortunately, the Xilinx design tools automatically compensate to make a successful connection without any manual modification. This connection is shown in the block diagram at circle "1." The advantage in making this type of connection is that it is very easy, and the DDR memory appears to the design as regular memory. The disadvantage is that AXI-Lite doesn't support burst mode and is only 32 bits wide, so you lose quite a bit of performance.
There are other ways to connect PL-based peripherals to the DDR memory as well, including the use of a DMA controller, likewise by means of the HP ports. While more complex, this mechanism offers better performance for transferring large blocks of data.
Within the PS, a UART and a triple timer/counter (TTC) are enabled. The M_AXI_GP0 connects to a BRAM controller that resides in the PL but is conceptually (and practically) part of the PS design.
The other portion of the design, the MicroBlaze, uses BRAMs to provide 64 Kbytes of combined code and data space for exclusive use by the MicroBlaze. It is certainly possible to connect these ports to the HP ports of the PS in order to access the DDR memory. However, doing so invites additional complexity in the implementation.
There are three standard peripherals attached to the MicroBlaze—an interrupt controller that receives the TTC's PWM waveform input and interprets it as an interrupt source and the UART-character received interrupt; a GPIO that drives the eight LEDs on the ZC702 board; and a BRAM controller that connects to the "B" side of the same BRAM that the PS connects to. Then there are two additional connections: one to the S_AXI_GP0 so that the peripherals internal to the PS can be addressed, and one to the high-performance ports so that the MicroBlaze has access to a portion of the DDR memory.
Peripherals, data blocks and synchronization
The key to accessing the programmable system's IOP block is the connection to the PS' S_AXI_GP0 port (circle "2" in the figure). The "S" denotes that this is a slave port—one that can accept transactions that elements in the PL initiate. When you make the connection between the MicroBlaze and the S_AXI_GP0 port, the IOP block spans the range of 0xE000_0000 to 0xE02F_FFFF. This means that no other peripherals in the MicroBlaze's address space can overlap this range of addresses, as they will be shared between the processors.
Meanwhile, a number of mechanisms support passing blocks of data between the MicroBlaze and the PS—DMA to and from DDR and on-chip memory (OCM) being but two possibilities. Another option, as implemented in the example design, uses a dual-port Block RAM (circle "3" in the figure). The PS masters one side of a BRAM controller while the MicroBlaze masters the other side. Software manages partitioning and use of the shared BRAM memory space, since both sides have full read/write access to the entire contents of this memory.
The final issue involves how to synchronize events between the MicroBlaze and the PS. The PS contains a plethora of timers, and you can instantiate virtually any number of timers in the PL. The example design uses one channel within one of the triple-timer/counter peripherals to generate a 100-millisecond pulse (circle "4" in the figure). The trick here is to realize that the TTC generates a waveform that is accessible outside the PS, but the TTC interrupt is only available inside the PS. You can get around this issue by using the waveform itself as an interrupt to the MicroBlaze processor. Alternatively, you may employ a hardware timer (whether an AXI timer or one that's user-coded) to provide an interrupt to both the PS and the MicroBlaze.
As with any embedded design, you must consider not only the hardware implementation, but the software support as well. For this example, consider the areas of overlap between the two processors, as outlined in Figure 5.
Figure 5. Independent software realms and items of overlap.
In terms of the hardware, think of the system as two intersecting embedded designs: the PS and the MicroBlaze. Our reference design has the PS generating the clocks for both itself and the MicroBlaze as well as sourcing the interrupts. The MicroBlaze can use these signals, but it can't influence or alter them. Both the PS and the PL share the PS' IOP block, the DDR memory and controller, and the common dual-port BRAM.
From an address map standpoint, the IOP addresses are fixed in hardware and cannot be modified. Both the MicroBlaze and the Cortex-A9 must use the same addresses for any of these peripherals. The Technical Reference Manual is especially helpful in this regard. There are two portions of the TRM that are useful for dealing with peripherals in this design: the sections on the specific peripheral (such as Section 8 – Timers and Section 19 – UART Controller), and Appendix "B," which lists all of the registers for each of the peripherals. Each register in this section is listed by its address along with a brief description. It is left as an exercise to the user to manage the resources between the two processors to avoid data collisions, starvation and so on.
Use of the DDR memory and its controller is a bit easier, since the DDR memory controller is capable of managing collisions and has appropriate heuristics to avoid data starvation for any of the requestors. Since this is not under user control, the latency may become a bit unpredictable.
The common BRAM will have identical lower address bits; however, the location in each processor's memory space for this block is selectable using the address tab in Xilinx Platform Studio. As before, data collisions, synchronization and memory allocation are left as an exercise to the reader.
Our example software design is more about demonstrating the process of connecting a Cortex-A9 with a MicroBlaze than doing anything practical. A couple of techniques will illustrate some of the possibilities in this regard.
The Zynq-7000 application shown in the left side of Figure 6 is a simple design that uses the Xilinx Standalone board support package. It runs a program that, for the most part, keeps the processor idling and periodically issues a "T" character (for "tic") via the serial port to indicate that it is still alive. Additionally, it counts the number of elapsed tics and places this count in the Block RAM that is shared with the MicroBlaze.
Figure 6. Flow diagram for both the Cortex-A9
application and the MicroBlaze application.
The MicroBlaze application also runs a Standalone board support package. This approach supports interrupts, and each time a character appears on the serial port the MicroBlaze buffers that character and echoes its Hex-ASCII equivalent back to the serial port in the PS' IOP block. Additionally, it builds a string of received characters and places it in the DDR memory for each character received. When a carriage return is received, a checksum is computed and added to the DDR memory immediately following the string. A flag is set in a predetermined location in BRAM and when the Cortex code "sees" this flag, it reads the string from the DDR memory and verifies the checksum. If the checksum is correct, the MicroBlaze emits a "+." Otherwise, it transmits an "X."
In short, our example design proves that the MicroBlaze and Zynq-7000 PS can coexist peacefully. The copious number of AXI connection points provide the MicroBlaze (or anything in the PL) easy access to the peripherals in the IOP block, the OCM and the DDR. The programmable logic can easily access interrupts from the IOP block, just as a number of interrupts can be generated in the PL and supplied to the PS. Software coordination and well-defined behavior are key to avoiding race conditions and addressing conflicts.
About the authors
Bill Kafig is a Senior Content Development Engineer at Xilinx. Bill can be contacted at firstname.lastname@example.org
Praveen Venugopal is a Solutions Development Engineer at Xilinx. Praveen can be contacted at email@example.com
If you found this article to be of interest, visit Programmable Logic Designline
where – in addition to my Max's Cool Beans
blogs – you will find the latest and greatest design, technology, product, and news articles with regard to programmable logic devices of every flavor and size (FPGAs, CPLDs, CSSPs, PSoCs...).
Also, you can obtain a highlights update delivered directly to your inbox by signing up for my weekly newsletter – just Click Here
to request this newsletter using the Manage Newsletters tab (if you aren't already a member you'll be asked to register, but it's free and painless so don't let that stop you [grin]).