Skip to content

LED blink

Pau Gómez edited this page Aug 17, 2023 · 34 revisions

About this tutorial

⏱️ 45 min

Key learnings:

  • Create a new Vivado project & block design

  • Use the AXI GPIO to write data from PS to PL

  • Write custom HDL modules

  • Define board constraints

  • Create a simple Jupyter Notebook to control the FPGA design

Description:

In this tutorial we are going to demonstrate how to blink the LEDs of your Redpitaya-125-14. The LEDs will be driven by the most-significant-bit (MSB) of a counter that continuously overflows. The counter is implemented within the Programable Logic (PL) and controlled through a simple PYQN Jupyter Notebook running on the Processing System (PS).

Building the Vivado Design

Create a new Vivado Project

  • Open Vivado and click on Create Project and hit Next.
  • Set the name of the new project (e.g. LED_blink) and hit Next.
  • Use the default project type (RTL Project) and hit Next.
  • Leave the Add Sources screen empty and hit Next.
  • Under the Boards tab select Redpitaya-125-14 (see here for instructions to install the Redpitaya-125-14 board files) and hit Next.
  • After finishing this initial configurations, a new Vivado Project is created. You will see the Project Manager page:

Create a new Block Design

  • Create a new block design by clicking on Create Block Design (left panel). The design name will default to design_1.
  • Right-click on the blank design and select Add IP to instantiate:
    • ZYNQ 7 Processing System
    • AXI GPIO (we will use this IP to write from PS to PL)
  • Click on Run Block Automation (green field above your design) to route the DDR and FIXED_IO ports of the ZYNQ instance. To this end, leave the configuration window in its default state.
  • Click on Run Connection Automation (green field above your design) to create the required clocking, reset and AXI interconnect infrastructure. To this end, within the configuration window only select S_AXI. We do not select GPIO, because we will manually configure & connect the AXI GPIO.
  • After running block & connection automation, the design becomes:
  • Double-click on the AXI GPIO instance and enable Channel 1 and Channel 2 as outputs of 1 and 32 bits, respectively. Later in the design process, we will use Channel 1 to reset the counter logic and Channel 2 to define the counter increment value.
  • Double-click on the ZYNQ instance and verify (under Clock Configuration --> PL Fabric Clocks) that FCLK_CLK0 is enabled and set to 50 MHz.

Create an HDL counter


ℹ️ Two main Hardware Description Languages (HDLs) exist: VHDL and Verilog. There is not a good answer to which language is better and it typically ends up being a matter of taste and your environment (colleagues, language of previously developed codes ...), that drives you to develop in one ore another. Vivado supports both languages and for this reason also all example codes of this tutorial come in pairs of .vhd and .v files.

  • The next step is to create a counter logic with variable counter increment. Click on Add Sources (left panel) and select Add or create design sources.
  • At this point you can either select and already existing HDL file or create a new one. We will follow the latter.
  • Define the module ports (they can also be changed later, within the HDL code).
  • The new source file (counter.vhd or counter.v) will be added to the project source tree.
  • Edit it to include the counter logic (see programming examples for counter.vhd or counter.v).

  • Add the HDL counter module to your design. To this end, right-click on the design and select Add Module.

Constraints and signal routing

  • Open the constraints file (redpitaya-125-14.xdc) and uncomment lines 166-177, which define and configure the FPGA ports connected to the LEDs.
  • Return to your design, right-click and select Create Port. Name the port led_o and configure it as shown below:
  • Now we need to connect the MSB of the HDL counter to the output port. For this purpose, instantiate:

    • Slice IP
    • Concat IP
  • Configure the Slice IP to accept a 32 bit wide input and return the MSB.

  • Configure the Concat IP to bundle 8 inputs (1 bit wide).
  • Wire up the AXI GPIO, HDL counter, Slice IP, Concat IP and led_o port as shown below:

Bitstream generation

  • Before bitstream generation, a HDL design wrapper needs to be created, which is an automatically generated HDL code that represents your graphical design.

    Within your project source tree, right-click on top of your design and select Create HDL Wrapper (use default settings).

  • Click on Generate Bitstream (left panel) and proceed with the default settings. This will automatically take you through:

    • Synthesis: translates the HDL wrapper (i.e. your custom FPGA design) into logical elements such as flip-flops, LUTs...
    • Implementation: places and routes the logical elements of the synthesized design into the particular chip architecture.
    • Bitstream generation: creates a binary image that contains the implemented design.
  • After a few minutes, the process completes. Press Cancel to close the pop-up window.

Running the design


ℹ️ Please make sure to complete first the steps in Prepare your Redpitaya-125-14 and Speed up the design flow.


  • Verify that you Redpitaya-125-14 is connected to your local network, e.g. using ping:
ping <static-ip-address>
  • Create and upload the overlay for your custom design by pressing the button. The following message should appear within your Vivado Tcl console:
Overlay "LED_blink" successfully uploaded to: 
xilinx@<static-ip-address>:/home/xilinx/pynq/overlays/LED_blink
  • Open your preferred web browser and navigate to <static-ip-address> and enter the PYNQ Jupyter Notebook environment (password: Xilinx).

  • Create a new Python 3 Jupyter Notebook.

  • Open the Jupyter Notebook and edit it as shown in FPGA-Notes-for-Scientists/jupyter_notebooks/LED_blink.ipynb.

  • Run the Jupyter notebook.

Next steps

See assignments on FPGA Pendulum Waves and PWM.