By Adam Taylor

So far we have looked at how we could instantiate the Xilinx PicoBlaze processor hardware within a system based on the Zynq SoC. In this blog, I am going to explore more on how we generate the PicoBlaze program and how we can update the program using the JTAG port without recompiling the design.

Obviously the first thing we need to do is write the assembler program that implements the desired function. We can do this using a program like Notepad++ or even a more advanced IDE like fidex (http://www.fautronix.com/en/fidex).

This assembly file should have the file extension of .PSM, for instance test.psm. The PicoBlaze processor is programmed using the Picoblaze assembler. Detailed information on the assembly syntax for the PicoBlaze processor is provided within UG129 and the file All_kcpsm6_syntax.psm, which comes with your download. The syntax is very easy to understand and learn.

The example we used last week to flash the LEDs uses the code below, which flashes four LEDSs on the IO Carrier card at 2Hz with the PicoBlaze processor running on a 40MHz clock. We will achieve this blink rate using a counter that counts down from a predefined number and toggles the LED status when it reaches zero.

The PicoBlaze an instruction in two clock cycles so we calculate the predefined blink count thus:

5s / 50ns = 10,000,000 cycles

However looking at the code below in the delay loop there are five instructions to be executed, therefore we need to divide the above number by 5, which gives a constant of 2,000,000—or 1E8480 in hex.

Here’s the resulting LED blink program code for the PicoBlaze processor:

NAMEREG s0,led ;rename S0 register to led

;As 8 bit processor we need four delay loops 256 * 256 * 256 * 256 = 4294967296

CONSTANT max1, 80 ;set delay

CONSTANT max2, 84 ;set delay

CONSTANT max3, 1e ;set delay

CONSTANT max4, 00 ;set delay

main: LOAD led, 00; load the led output register with 00

flash: XOR led, FF; xor the value in led register with FF i.e. toggle

OUTPUT led,01; output led register with port ID of 1

CALL delay_init; start delay

JUMP flash; loop back to beginning

delay_init: LOAD s4, max4;

LOAD s3, max3;

LOAD s2, max2;

LOAD s1, max1;

delay_loop: SUB s1, 1'd; subtract 1 decimal from s1

SUBCY s2, 0'd; carry subtraction

SUBCY s3, 0'd; carry subtraction

SUBCY s4, 0'd; carry subtraction

JUMP NZ, delay_loop;

RETURN

The next step is to run this source listing through the assembler that came with your PicoBlaze download to generate a memory file (in VHDL for use within your FPGA which we used last week), a log file, and a hex file.

Having written the program, we can instantiate it as we did last week within our design. However if we need to change the program behavior during integration testing, one method is to use the JTAG loader which also comes with the download. The JTAG loader allows us to modify the PicoBlaze processor’s RAM contents using the JTAG interface. Then we can test the updated program before we rebuild the FPGA configuration with the updated program so that it runs from RAM automatically.

We can use the JTAG loader on one instance of the PicoBlaze only. If there are several PicoBlaze instances within the design—yes, that’s definitely allows—we need to ensure only one processor has the JTAG loader enabled. We achieve this by using the JTAG loader Generic in the PicoBlze instantiation thus:

Having set the JTAG loader for only one of our PicoBlaze instantiations, we can then use the JTAG loader which comes with the program to download modified code using the Hex file generated when we assemble a program.

The process is simple. First select the correct version for the operating system you are using from the JTAG_loader directory of the download and copy it to your working directory (where you hex file is located). Once this has been completed, you can open a command window and navigate to your working directory and use the command below:

jtagloader –l <Your Project Name>.hex

Note, I have renamed the version of the executable for my OS jtagloader.exe

As this downloads you will notice that the JTAG loader halts the core execution and downloads the new program to memory before releasing the core reset, at which point your new program starts running.

While a very powerful utility like this allows you to download and verify program modifications, it does have a few draw backs, unfortunately. For example, the next time you power cycle the board, the original program—not the updated one—will be executed. Also, you cannot update more than one PicoBlaze instance without generating a new FPGA configuration.

Thankfully the architecture of the Zynq enables us to overcome both of these limitations and we will be looking at how we achieve this over the next few blogs. It is really quite exciting.

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

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