Bare metal ZPU "Hello world"


Recommended Posts



here is an example project (download) that shows how to

  • create a ZPU on a Papilio Pro board
  • compile a C program (gcc)
  • insert the bit stream
  • simple IO (no wishbone bus)
  • integrate the ZPU into Verilog (rewriting the top-level file in VHDL would be trivial.

Anything that's not essential is removed.

For those who haven't yet met one: The ZPU is a tiny microcontroller with a GCC development environment.


Most of the code is borrowed from here.

My contribution is to remove stuff to the point where it barely works - it's still complicated enough. zpu_config.vhd was largely rewritten.

There is one clock input, one LED output, and that's all.


Cygwin is required to compile C code. The ZPU compiler binaries are included.


Step 1: Check that the pre-built binary works

  • Start Papilio loader;
  • select "uploadme.bit" as "Target .bit file".
  • "Write to: FPGA" is fastest

On completion, the LED should blink slowly


Step 2: Compile your own binary

  • Edit c-code/main2.c (there are 3 blink variants to choose from, edit #if... /#elif)
  • Run You may have to edit it once and set correct paths
  • If successful, the new binary is copied to the bitstream
  • repeat Step 1 and the LED should blink differently.

Step 3: Rebuild the project (Xilinx ISE 14.7 web edition)

  • For example, in src/zpu_config.vhd, change
    constant maxAddrBitIncIO    : integer := 15;
    to 16.
  • Now the C code won't control the LED anymore, until it is changed from
    volatile unsigned int* io = (unsigned int*)0x00008000;
    volatile unsigned int* io = (unsigned int*)0x00010000;
Link to comment
Share on other sites


This topic is now archived and is closed to further replies.