By Adam Taylor

In the previous instalment of the MicroZed Chronicles, we looked at the traditional method for updating and modifying PicoBlaze programs using the JTAG loader. The Zynq SoC’s PS (Processing System) provides additional capabilities that allow us to create a more flexible PicoBlaze program-loading system for a little more work. We can use the Zynq PS to access the BRAM memory on the Zynq SoC’s PL (Programmable Logic) where the PicoBlaze program resides. We will do this using the AXI BRAM controller. We explored the BRAM controller previously in the MicroZed Chronicles’ NeoPixel example.

This approach does require a little more manipulation because we cannot use the memory VHDL file generated by the PicoBlaze assembler. However, we’ll be using standard IP modules so it’s not significantly more difficult. Instead, we first create a dual-port RAM and initialize it with the contents of the hex file generated by the PicoBlaze assembler so that there will be an executable program in the PicoBlaze processor’s memory following power up.

The program we place in the dual-port RAM works no differently than the VHDL file generated by the assembler. However that program ran from a single-port memory. The addition of the second RAM port allows the ARM Cortex-A9 MPCore processors in the Zynq PS to access the shared, dual-port memory and overwrite the contents of that memory if required during development. This technique makes it easy to change the PicoBlaze processor’s executable program as required.

One example where it’s advantageous to be able to reprogram the PicoBlaze processor in the system is for generating waveforms to drive a CCD (Charge Coupled Device) for imaging. The deterministic nature of the PicoBlaze processor is well suited to generating these waveforms. However, CCD imaging devices can often require modified waveform timings during run time to achieve optimal imaging performance. Therefore the ability to modify these waveforms on the fly is very important and using a software-driven approach is extremely convenient.

We add a dual-port memory to our PicoBlaze processor by right clicking on the PicoBlaze component within the block diagram and selecting “edit in IP packager.” This will open the IP packager and allows us to modify the component we previously created. The first thing to do is to remove the memory file VHDL from the project and create a new dual-port memory using the IP Catalog to add a new block memory generator.

The settings for ports A and B of the dual-port memory are very simple. Port A will be interfaced to the AXI BRAM controller and port B to the PicoBlaze. Configure the RAM as below:

Interface type native

True Dual Port RAM

Port A Options Write Width 32 Read Width 32 Use 32 bit addressing – as required by the AXI BRAM Controller Operating mode Write First Enable Port Type Use ENA Pin

Port B Options Write Width 18 Read Width 18 Use 32 bit addressing Operating mode Read First Enable Port Type Use ENA Pin Ensue the Primitives Output Register is not Enabled



We wish to use an INIT file to preconfigure the BRAM contents so we need a Xilinx COE file, which we’ll specify using the “Other Options” tab. We can use the HEX file generated by the PicoBlaze assembler. You simply need to add the following line to the top of the file:

memory_initialization_radix=16;

memory_initialization_vector=

You can then add the file to initialize the PicoBlaze processor’s memory contents, which will be executed by the PicoBlaze at power up.

We are using 32-bit addressing so we need to ensure that memory accesses form the PicoBlaze to the block RAM are correctly aligned. Thus we need to ensure the first two LSBs of the 32-bit memory address are not used, which will automatically ensure word alignment.

Now we can connect the dual-port RAM within the top of our PicoBlaze component and re-package the IP, enabling us to update the PicoBlaze instance within the block diagram. (Use Tools -> Report -> Report IP Status if it does not update automatically.) With the IP now up to date, we can add in the AXI BRAM controller and connect it to the Zynq SoC’s processor AXI bus. Doing so will allow the ARM Cortex-A9 MPCore processors in the Zynq PS to read and write the dual-port memory that’s connected to the PicoBlaze processor and from which the PicoBlaze processor executes its program.

This implementation allows us to change the PicoBlaze program as required by the application. You can consider this technique as a kind of partial reconfiguration for the PicoBlaze processor. Loading new programs into the dual-port RAM changes the function performed by the PicoBlaze processor in the system on the fly, if required, to perform different operations or for debug / experimentation. We can also update more than one PicoBlaze processor in a Zynq system using this approach.

The next blog in this series will continue to look at this technique. We will be controlling and updating two PicoBlaze processors within the PL side of the Zynq device as shown below:

Please see the previous entries in this MicroZed series by Adam Taylor:

Adam Taylor’s MicroZed Chronicles Part 57: The Zynq and the PicoBlaze Part Two

Adam Taylor’s MicroZed Chronicles Part 56: The Zynq and the PicoBlaze

Adam Taylor’s MicroZed Chronicles Part 55: Linux on the Zynq SoC

Adam Taylor’s MicroZed Chronicles Part 54: Peta Linux SDK for the Zynq SoC

Adam Taylor’s MicroZed Chronicles Part 53: Linux and SMP

Adam Taylor’s MicroZed Chronicles Part 52: One year and 151,000 views later. Big, Big Bonus PDF!

Adam Taylor’s MicroZed Chronicles Part 51: Interrupts and AMP

Adam Taylor’s MicroZed Chronicles Part 50: AMP and the Zynq SoC’s OCM (On-Chip Memory)

Adam Taylor’s MicroZed Chronicles Part 49: Using the Zynq SoC’s On-Chip Memory for AMP Communications

Adam Taylor’s MicroZed Chronicles Part 48: Bare-Metal AMP (Asymmetric Multiprocessing)

Adam Taylor’s MicroZed Chronicles Part 47: AMP—Asymmetric Multiprocessing on the Zynq SoC

Adam Taylor’s MicroZed Chronicles Part 46: Using both of the Zynq SoC’s ARM Cortex-A9 Cores

Adam Taylor’s MicroZed Chronicles Part 44: MicroZed Operating Systems—FreeRTOS

Adam Taylor’s MicroZed Chronicles Part 43: XADC Alarms and Interrupts

Adam Taylor’s MicroZed Chronicles MicroZed Part 42: MicroZed Operating Systems Part 4

Adam Taylor’s MicroZed Chronicles MicroZed Part 41: MicroZed Operating Systems Part 3

Adam Taylor’s MicroZed Chronicles MicroZed Part 40: MicroZed Operating Systems Part Two

Adam Taylor’s MicroZed Chronicles MicroZed Part 39: MicroZed Operating Systems Part One

Adam Taylor’s MicroZed Chronicles MicroZed Part 38 – Answering a question on Interrupts

Adam Taylor’s MicroZed Chronicles Part 37: Driving Adafruit RGB NeoPixel LED arrays with MicroZed Part 8

Adam Taylor’s MicroZed Chronicles Part 36: Driving Adafruit RGB NeoPixel LED arrays with MicroZed Part 7

Adam Taylor’s MicroZed Chronicles Part 35: Driving Adafruit RGB NeoPixel LED arrays with MicroZed Part 6

Adam Taylor’s MicroZed Chronicles Part 34: Driving Adafruit RGB NeoPixel LED arrays with MicroZed Part 5

Adam Taylor’s MicroZed Chronicles Part 33: Driving Adafruit RGB NeoPixel LED arrays with the Zynq SoC

Adam Taylor’s MicroZed Chronicles Part 32: Driving Adafruit RGB NeoPixel LED arrays

Adam Taylor’s MicroZed Chronicles Part 31: Systems of Modules, Driving RGB NeoPixel LED arrays

Adam Taylor’s MicroZed Chronicles Part 30: The MicroZed I/O Carrier Card

Zynq DMA Part Two – Adam Taylor’s MicroZed Chronicles Part 29

The Zynq PS/PL, Part Eight: Zynq DMA – Adam Taylor’s MicroZed Chronicles Part 28

The Zynq PS/PL, Part Seven: Adam Taylor’s MicroZed Chronicles Part 27

The Zynq PS/PL, Part Six: Adam Taylor’s MicroZed Chronicles Part 26

The Zynq PS/PL, Part Five: Adam Taylor’s MicroZed Chronicles Part 25

The Zynq PS/PL, Part Four: Adam Taylor’s MicroZed Chronicles Part 24

The Zynq PS/PL, Part Three: Adam Taylor’s MicroZed Chronicles Part 23

The Zynq PS/PL, Part Two: Adam Taylor’s MicroZed Chronicles Part 22

The Zynq PS/PL, Part One: Adam Taylor’s MicroZed Chronicles Part 21

Introduction to the Zynq Triple Timer Counter Part Four: Adam Taylor’s MicroZed Chronicles Part 20

Introduction to the Zynq Triple Timer Counter Part Three: Adam Taylor’s MicroZed Chronicles Part 19

Introduction to the Zynq Triple Timer Counter Part Two: Adam Taylor’s MicroZed Chronicles Part 18

Introduction to the Zynq Triple Timer Counter Part One: Adam Taylor’s MicroZed Chronicles Part 17

The Zynq SoC’s Private Watchdog: Adam Taylor’s MicroZed Chronicles Part 16

Implementing the Zynq SoC’s Private Timer: Adam Taylor’s MicroZed Chronicles Part 15

MicroZed Timers, Clocks and Watchdogs: Adam Taylor’s MicroZed Chronicles Part 14

More About MicroZed Interrupts: Adam Taylor’s MicroZed Chronicles Part 13

MicroZed Interrupts: Adam Taylor’s MicroZed Chronicles Part 12

Using the MicroZed Button for Input: Adam Taylor’s MicroZed Chronicles Part 11

Driving the Zynq SoC's GPIO: Adam Taylor’s MicroZed Chronicles Part 10

Meet the Zynq MIO: Adam Taylor’s MicroZed Chronicles Part 9

MicroZed XADC Software: Adam Taylor’s MicroZed Chronicles Part 8

Getting the XADC Running on the MicroZed: Adam Taylor’s MicroZed Chronicles Part 7

A Boot Loader for MicroZed. Adam Taylor’s MicroZed Chronicles, Part 6

Figuring out the MicroZed Boot Loader – Adam Taylor’s MicroZed Chronicles, Part 5

Running your programs on the MicroZed – Adam Taylor’s MicroZed Chronicles, Part 4

Zynq and MicroZed say “Hello World”-- Adam Taylor’s MicroZed Chronicles, Part 3

Adam Taylor’s MicroZed Chronicles: Setting the SW Scene

Bringing up the Avnet MicroZed with Vivado