Sunday, April 20, 2014

ZYBO and onboard USB/UART interface

Xilinx's XUP FPGA Design Flow, Lab 3

A moderately frustrating thing about Xilinx's tutorial "FPGA Design Flow" is that it requires a USB to UART interface directly connected to the FPGA fabric. Had I known this when I ordered the ZYBO, I would have also gotten the appropriate peripheral module from digilent, but as it is I find I am unwilling to pay the over $10 shipping for a $20 module which must be only a handful of ounces in weight. Luckily, I was able to get my hands on a spare bluetooth module with a Pmod-like interface - easily modifiable to work with digilent's pmod specification.

An alternative to the pmod would be to pass the on-board USB/UART through the PS to the PL. And the lab manual states right at the beginning that "You will use on-board UART of the ZYBO board to validate your design." But in reality, this requires creating a Zynq boot image - a simple process, I'm sure, but that's for the next of Xilinx's XUP tutorials on Embedded Systems. So, for now, I'll try to work with this bluetooth module.

Update

A friend loaned me a USB to UART module that ended up working just fine! It was powered on the USB side so I only needed to connect the ground and RXD pins on the receiver shown here:
hand-wired USB-UART module. The module's GND and TXD are
connected to the ZYBO's GND and RXD receiving slots
This module probably set my friend back less than $5 US and I was able to finish lab #3 in the FPGA Design Flow lessons from Xilinx's XUP.

Sunday, April 13, 2014

Buttons and Switches on the ZYBO

Controlling the LEDs with switches and buttons

This is an embellishment of the previous post on programming the FPGA on the ZYBO board to control the LEDs. This time I programmed the first LED to merely blink at 1 Hz with an enable switch and reset button. The other three LEDs are controlled by a single logic gate (AND, OR and XOR) between the corresponding switch and button. Here is the code - all steps in my previous post apply, though all the buttons and switched will have to be uncommented in the XDC file in addition to the LEDs.

`timescale 1ns / 1ps

module switches_and_buttons(
    output reg [3:0] led,
    input [3:0] btn,
    input [3:0] sw,
    input clk
    );

reg [25:0] counter;
reg one_sec_clk;

wire rst;
wire en;

assign rst = btn[0];
assign en = sw[0];

always @ (posedge clk) begin
    if (rst) begin
        counter <= 0;
        one_sec_clk <= 0;
    end else if (en) begin
        if (counter == 26'd62500000) begin
            counter <= 0;
            one_sec_clk <= ~one_sec_clk;
        end else begin
            counter <= counter + 1;
        end
    end
end

always @ (one_sec_clk, btn, sw) begin
    led[0] = one_sec_clk;
    led[1] = btn[1] || sw[1];
    led[2] = btn[2] ^  sw[2];
    led[3] = btn[3] && sw[3];
end

endmodule

As you can see, I have a counter running to 62.5M, cutting the 125 MHz clock in half. The reset (rst) is attached to the first button (btn[0]) and the enable (en) is attached to the first switch (sw[0]). The other button/switch pairs are used to set the remaining LEDs in the second (combinational) always block and are operating rather independently of the first blinking LED.

First Steps with the ZYBO Development Board

ZYBO Development Board

I just received Xilinx's ZYBO educational FPGA development board in the mail from diligent. This is my first venture into anything like digital logic, ASICs or FPGAs and my goal is to become familiar with the workflow using Xilinx's Vivado on Linux and to gain some knowledge concerning the capabilities and limitations of FPGA programming.


Attractive box containing the ZYBO
The ZYBO board powered over USB
The Zynq-7010 chip consists of a very modest FPGA with 28k logic element, but a dual-core 650 MHz ARM processor sits on the same die. As far as I understand things right now, this means the CPU could handle the I/O protocol over USB, pushing data through the FPGA for some specific operations that would be too slow if implemented on the ARM.


Vivado on Linux

I also purchased the accessory kit which came with a Vivado Design Suite voucher - and while I did get this to work, it wasn't seamless. I am running the Fedora operating system with Linux kernel version 3.13.9 on an i5 Asus Zenbook. The hard drive on this laptop is only 128 GB so I installed Vivado onto a USB drive. I wasn't able to get Xilinx's downloader to work on any linux machine, but I obtained a direct link (which expired already) to the 7 GB file and used curl with the "-C -" option to allow for interruptions.

So, I untar'd this file and ran the xsetup script as root, installing everything into the directory above, but still on the USB drive. It complained about not being able to install some drivers, but in the end I was able to ignore this.

I found out that Xilinx includes nice environment setup files only after I spent a long time writing my own. There seems to be only one that matters and I added this to my .zshrc file:

alias vivado="bash -ilc 'source /path/to/Vivado/2013.4/settings64.sh && vivado'"

The license was slightly tricky. I created an account with Xilinx and used their website to obtain a .lic file. It wanted two things at least to identify the computer I would use: the hostname and the ethernet MAC address. So first, in Vivado, I clicked on "Help" -> "Manage License..." A window came up and at the bottom of the "Manage Licenses" tab I saw a hostname and all zeros for the NIC ID. The hostname was the usual "aaa.bbb.ccc" format but the website only accepted the "aaa" part -- it disallowed periods in the hostname. The website license generator was perfectly happy with all zeros for the MAC address. Clicking on "Load License..." I imported the .lic file received from Xilinx and everything seemed to work out fine.


Creating a New Project in Vivado

The steps to go from nothing to a programmed FPGA, bypassing all features of the ZYBO but the four user LEDs on the board and the FPGA's internal clock, took the better part of an afternoon and while this post helped a lot, there were enough differences with the newest version of Vivado (2013.4) to warrant creating a new tutorial, hence this blog.

First off, Java applications like eclipse (what Vivado is based on) have a tendency to get confused when the window is resized. The mouse cursor is somehow offset when I maximize the window, making the program unusable since it is very mouse-centric. The solution was to first move the window to the upper-left corner and then maximize it.

I clicked on "Create New Project" and followed the wizard, creating an "RTL Project" and checked the box for "Do not specify sources at this time." The ZYBO board is still not listed under "Boards," but the part was easy enough to find. The part number is xc7z010clg400 and I chose speed grade "-1" though I was not bothered to look up what this meant.


Vivado New Project Wizard Part Chooser
This was the last step before the wizard showed a summary and I was ready to start adding what Xilinx calls "Design Sources" which include the HDL code (modules in verilog) and netlists.


A Simple Counter in HDL (Verilog)

There are four user LEDs directly connected to the FPGA on the ZYBO. As a "Hello, World." program, I decided to make a clock out of these counting from 0 to 15 using the internal clock on the FPGA. Though one could create a module with inputs and output and connect these to pins using the "Elaborated Design" part of Vivado, there is a better way with the constraints file which can be downloaded from Digilent's website -- you want the master XDC file for Vivado. I clicked on "Add Sources" then "Add Constraints File" and pointed to the downloaded XDC file. I opened this up and searched for "clock" and "led" and found exactly what I was looking for. There are two lines for each pin which must be uncommented, but then the port names can be used directly in the source files.

Clock pin L16 in the XDC file (uncommented)

LED pins in the XDC file (uncommented)

Next, I clicked on "Add Sources" again but this time created a "Design Source." Here is my simple clock done up in verilog. The 125000000 comes from the clock I'm using which is 125 MHz according to the ZYBO reference paper - I wanted the LED clock to update once a second. Notice I used the same names as in XDC file, namely "led" and "clk."

LED counter using a 125 MHz clock
Double clicking on "Generate Bitstream" eventually worked -- there were a couple problems here and there, but they were deviations from the steps above. The final step was to push this little gem onto the ZYBO itself.

Programming the FPGA

The old Xilinx ISE program iMPACT is not packaged with Vivado (I lied when I said this was my first experience with FPGAs). Instead, you have to setup a "VCSE Server" running as root which will handle talking to the board. This is simple enough and I find it much preferable to dealing with udev rules or running all of Vivado as root. So, as root I run this alias:

alias vcse_server='source /path/to/Vivado/2013.4/settings64.sh && vcse_server'

After that, I plugged the ZYBO into a USB port on my laptop via the PROG/UART connector on the board and turned it on. The VCSE server didn't show anything yet. In Vivado, I switched to the "Hardware Manager" and clicked on "Open a new hardware target."

Selecting the ZYBO in the Hardware Manager wizard
Selecting Frequency
I left the default frequency of 150 MHz unchanged and finished this wizard. Finally, there was an option to program the device. This took only a moment and the LEDs immediately started to count.

LEDs on count 11