LED blinker


For my experiments with the Red Pitaya, I’d like to have the following development environment:

Here is how I set it all up.


My development machine has the following installed:

The installation of the development machine is described at this link.

Here are the commands to install all the other required packages:

sudo apt-get update

sudo apt-get --no-install-recommends install \
  build-essential git curl ca-certificates sudo \
  libxrender1 libxtst6 libxi6 lib32ncurses5 \
  bc u-boot-tools device-tree-compiler libncurses5-dev \
  libssl-dev qemu-user-static binfmt-support \
  dosfstools parted debootstrap zerofree

sudo ln -s make /usr/bin/gmake

Source code

The source code is available at


This repository contains the following components:

Syntactic sugar for IP cores

The projects/led_blinker directory contains one Tcl file block_design.tcl that instantiates, configures and interconnects all the needed IP cores.

By default, the IP core instantiation and configuration commands are quite verbose:

create_bd_cell -type ip -vlnv xilinx.com:ip:processing_system7:5.5 ps_0

set_property CONFIG.PCW_IMPORT_BOARD_PRESET cfg/red_pitaya.xml [get_bd_cells ps_0]

connect_bd_net [get_bd_pins ps_0/FCLK_CLK0] [get_bd_pins ps_0/M_AXI_GP0_ACLK]

With the Tcl’s flexibility, it’s easy to define a less verbose command that looks similar to the module instantiation in Verilog:

cell xilinx.com:ip:processing_system7:5.5 ps_0 {
  PCW_IMPORT_BOARD_PRESET cfg/red_pitaya.xml
} {

The cell command is defined in the scripts/project.tcl script as follows:

proc cell {cell_vlnv cell_name {cell_props {}} {cell_ports {}}} {
  set cell [create_bd_cell -type ip -vlnv $cell_vlnv $cell_name]
  set prop_list {}
  foreach {prop_name prop_value} [uplevel 1 [list subst $cell_props]] {
    lappend prop_list CONFIG.$prop_name $prop_value
  if {[llength $prop_list] > 1} {
    set_property -dict $prop_list $cell
  foreach {local_name remote_name} [uplevel 1 [list subst $cell_ports]] {
    set local_port [get_bd_pins $cell_name/$local_name]
    set remote_port [get_bd_pins $remote_name]
    if {[llength $local_port] == 1 && [llength $remote_port] == 1} {
      connect_bd_net $local_port $remote_port
    set local_port [get_bd_intf_pins $cell_name/$local_name]
    set remote_port [get_bd_intf_pins $remote_name]
    if {[llength $local_port] == 1 && [llength $remote_port] == 1} {
      connect_bd_intf_net $local_port $remote_port
    error "** ERROR: can't connect $cell_name/$local_name and $remote_name"

Getting started

Setting up the Vivado environment:

source /opt/Xilinx/Vivado/2016.4/settings64.sh

Cloning the source code repository:

git clone https://github.com/pavel-demin/red-pitaya-notes
cd red-pitaya-notes

Building boot.bin, devicetree.dtb and uImage:

make NAME=led_blinker all

Building a bootable SD card:

sudo sh scripts/debian.sh /dev/mmcblk0

SD card image

Building a bootable SD card image:

sudo sh scripts/image.sh scripts/debian.sh red-pitaya-debian-8.6-armhf.img 1024

The SD card image size is 1 GB, so it should fit on any SD card starting from 2 GB.

To write the image to a SD card, the dd command-line utility can be used on GNU/Linux and Mac OS X or Win32 Disk Imager can be used on MS Windows.

The default password for the root account is changeme.

A pre-built SD card image can be downloaded from this link.

Resizing SD card partitions on running Red Pitaya:

# delete second partition
echo -e "d\n2\nw" | fdisk /dev/mmcblk0
# recreate partition
parted -s /dev/mmcblk0 mkpart primary ext4 16MB 100%
# resize partition
resize2fs /dev/mmcblk0p2

Reprogramming FPGA

It’s possible to reprogram the FPGA by loading the bitstream file into /dev/xdevcfg:

cat led_blinker.bit > /dev/xdevcfg