Abstract: This ’blog describes my first experiments using a ValentF(x) LOGI-Bone FPGA board. After a short overview of LOGI-Bone and its Xilinx Spartan-6 FPGA, we show how to download two examples. The first is a pre-tested LED demo from ValentF(x) and the second is created from Verilog source code using Xilinx tools.
Disclaimer: This ’blog is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY. Incorrect board connections and/or an incorrect FPGA bitstream could cause damage to an FPGA and/or its connected circuitry, or cause a system to malfunction. Users must agree that the author has NO LIABILITY for any damages.
For a LOGI-Pi version of this ’blog, see First Experiments with the ValentF(x) LOGI-Pi.
The ValentF(x) LOGI-Bone is a new FPGA development board for the BeagleBone, both White and Black. Its chief advantage over other FPGA boards is that 27 (optionally 29) BBone pins connect directly to the FPGA so you have a flexible high-speed, low-latency connection. LOGI-Bone also has expansion sockets compatible with 3.3V Arduino UNO, DUE, and DUEM shields as well as two Digilent Pmod™ sockets. These connectors provide many options for add-on boards with all sorts of analog and digital capabilities. By going with standard connectors ValentF(x) doesn’t have to design and support those add-on boards themselves.
Here is the annotated layout of LOGI-Bone, from ValentF(x)’s LOGI-Bone User Guide, copied with permission:
In addition to the FPGA and expansion sockets LOGI-Bone has a 32 MB SDRAM, two LEDs, two push buttons, and two DIP switches, all of which are connected to FPGA pins for your use.
The heart of LOGI-Bone is a Xilinx Spartan-6 LX9 FPGA in a TQ144 package. This is a modern, high-performance FPGA which is currently the Xilinx price/performance “sweet spot”. Here are the main features of the LX9:
- Programmable array of logic cells with 5720 6-input Look-Up Tables (LUTs), 11,440 flip-flops, and carry-chain logic. Each 6-input LUT can be treated as two 5-input LUTs with shared inputs, and 1/4 of them can be used as high-speed 64-bit distributed RAM cells with various single- and multi-port configurations.
- 32 Block RAMs, each 18Kb for a total of 576 Kb (64KB with 9-bit bytes). Each Block RAM has two independing read/write ports which can have different data widths.
- 16 DSP slices, each with an 18x18 multiplier, adder, and accumulator.
- 2 clock managers with PLLs.
- 16 fast low-skew global clock distribution networks.
This same FPGA is used by a number of other FPGA development boards including Gadget Factory’s Papilio Pro and their upcoming Papilio DUO, Embedded Micro’s Mojo V3, XESS Xula2-LX9 (1.0mm pitch BGA), and Scarab Hardware’s upcoming miniSpartan6+ (also BGA). These boards have prices similar to LOGI-Bone but do not plug into BeagleBone headers.
Spartan-6 Configuration Options
Spartan-6 is an SRAM-based FPGA, which means that when you first turn on power the FPGA is unconfigured and remains so until you write a configuration bitstream into it. A bitstream is a 340KB file that defines the configuration of logic cells, routing, I/O pads, clocks, and block memory contents. Each of the 2.7 million bits in the file sets an SRAM bit in the FPGA -- some people describe an SRAM FPGA as an large SRAM with some logic attached to it.
There are several ways to write a bitstream to LOGI-Bone’s FPGA. By default, BBone writes the bitstream by running an FPGA loader program or simply copying a bitstream file to /dev/logibone. The LOGI-Bone device driver uses SPI to transfer the bitstream’s data bits, plus I²C for various FPGA control signals that don’t need to be fast. Xilinx calls this Slave Serial mode since an external master -- in this case BBone -- is treating the FPGA as a slave device.
You can modify LOGI-Bone to configure itself from a serial Flash chip that’s included on the board. This is called Master Serial/SPI mode because the FPGA is in control of its own configuration. You would typically use this mode for a stand-alone LOGI-Bone application that only uses BBone for development.
But wait! There’s more! You can also use JTAG to configure the FPGA if you solder a 6-pin header onto LOGI-Bone. JTAG can overwrite the bitstream configured by either of the other two modes. For JTAG you need an external JTAG module that typically plugs into a PC USB port. You can use the JTAG port to program LOGI-Bone if you don’t have a BeagleBone.
In this ’blog we will be using the default Slave Serial mode with BBone writing the bitstream.
By default, LOGI-Bone is powered from BBone’s “System 5V” rail. SYS-5V can come from either BBone’s Mini USB device port or BBone’s 5V power jack. Using the USB port for power is generally not the best idea, because by default it’s limited to 500 mA which may not be enough for both BBone and LOGI-Bone (plus any plugged-in interfaces) depending on what each board is doing. It’s a lot safer to plug an external power supply into BBone’s 5V power jack, which can accept up to 2A (perhaps more). Be sure your power supply provides regulated 5V (+/-5%) and has the proper plug polarity, as specified in BBone documentation.
LOGI-Bone also has holes for a two-pin header if you want to provide it with its own power, e.g., for stand-alone applications. If BBone is also powered, don’t use the LOGI-Bone header unless you know what you’re doing. In particular, make sure that if only one of the boards is powered this is not going to damage unpowered chips on the other.
For this ’blog I’m powering BBone using the 5V power jack and letting BBone’s SYS-5V provide power to LOGI-Bone as usual.
LOGI-Bone has linear regulators to convert SYS-5V to 3.3V for FPGA I/O and from 3.3V to 1.2V for FPGA core logic. These regulators could get hot if the FPGA is doing a lot. Some newer FPGA boards like Papilio Pro and DUO have switching regulators for these voltages which can save a lot of power.
Preparing BeagleBone GNU/Linux for LOGI-Bone
Before using LOGI-Bone, make sure your BBone’s operating system has the necessary device drivers. My BBone is running BBone Debian 7.5 2014-05-14 downloaded from BeagleBoard.org Latest Firmware Images. It has Linux kernel 3.8.13-bone50 and includes LOGI-Bone drivers /dev/logibone and /dev/logibone_mem. ValentF(x) has other images that work with LOGI-Bone: see Logi-Bone Quick Start Guide.
You will need to use an x86 PC to run Xilinx software to generate bitstreams. The PC needs to transfer those bitstream files to your BBone and you need a way to tell your BBone to write bitstreams to LOGI-Bone. There are various ways to do this, but for this ’blog I’ll concentrate on what I do with my BBone setup.
I have a minimal BeagleBone configuration with a 256MB BBone White, no capes installed other than the LOGI-Bone, and no attached keyboard, mouse, or display. I use a GNU/Linux PC running Ubuntu 12.04 LTS to talk to BBone over Ethernet, using either a Terminal window with ssh (secure shell) or X Windows to run BBone programs that have GUIs. This minimal configuration works well for LOGI-Bone development since you can use the PC’s display, keyboard, and mouse for everything.
To talk to the BBone from the PC, you need to know the user name and password of a BBone user who has superuser privileges. I’m going to call this user george. You can also use the default user debian if you don’t want to create a separate user.
You also need to know BBone’s IP address. It’s normally assigned automatically using DHCP by a router or the PC. My BBone’s IP address is 192.168.0.106, which I found by giving the ifconfig command on BBone when talking to it as a serial terminal over USB (this requires a BBone White). You can also talk to BBone using Network over USB at 192.168.7.2 provided that your PC OS has the correct drivers. For various ways to connect to BBone so you can get its IP address, see Logi-Bone Quick Start Guide, Getting Started with BeagleBone & BeagleBone Black, Adafruit’s SSH to BeagleBone Black over USB, or BeagleBone: Getting Started.
Finally, george needs a subdirectory for storing LOGI-Bone bitstreams. I’ll assume this subdirectory is called LOGI with full BBone path /home/george/LOGI or ~george/LOGI.
Experiment 1: Writing a Pre-tested Bitstream to LOGI-Bone
The procedure in this section uses GNU commands entered in two PC Terminal windows, one for the PC and one for BBone. If you prefer GUIs and/or your PC is running Windows, ValentF(x) has other procedures with a GUI equivalent for scp and an alternative to dd: see Logi-Bone Quick Start Guide.
Here are the commands I use on my BeagleBone setup. The commands should be similar on other setups. If you need help, please ask questions in the comments. As with most GNU/Linux commands, use man to get reference information. For example, the command “man ssh” describes how to use ssh.
To keep things clear, I will prefix commands entered on the PC with “PC$” and those entered on BBone with “BBone$”. I’ll use 192.168.0.106 as my BBone IP address and george as my user name -- you’ll need to substitute your own.
- With power off, plug LOGI-Bone onto your BBone. Be sure the two 46-pin connectors are lined up and that the BBone Ethernet jack is in LOGI-Bone’s notch. Carefully squeeze the boards together until the LOGI-Bone pins are fully inserted in the BBone sockets.
- Plug 5V power into the BBone’s power jack and connect an Ethernet cable between BBone and your router or Ethernet switch, or directly to your PC.
Alternatively, you can connect a USB cable between BBone and your PC and use Network over USB. In this case plug 5V power in before connecting the USB cable, or else BBone will try to power itself from USB which may not provide enough current.
- The BBone and LOGI-Bone power LEDs should turn on and you should see lots of activity on the other BBone LEDs as the operating system boots. One of the BBone LEDs is a “heartbeat” that tells you the OS is running OK.
- After giving BBone time to boot, open a Terminal window on your PC and ping BBone so you know you can talk to it:
PC$ ping 192.168.0.106
ping should show a series of successful data transfers and you should see BBone’s Ethernet activity LED blink as the pings occur.
- Log onto BBone using ssh and the IP address you verified in the last step. On your PC, give the command:
PC$ ssh email@example.com
The first time I did this ssh asked me to confirm that this was correct. Then ssh asks for george’s BBone password. If the BBone user name is the same as your PC user name you can simply write:
PC$ ssh 192.168.0.106
Once ssh has accepted the password, you’re in a command shell on BBone and you can enter GNU commands exactly as if you were on a BBone serial port or directly-attached display and keyboard.
- You are now in george’s home directory on BBone. Let’s change to the LOGI directory:
BBone$ cd LOGI
- Back on the PC, open another Terminal for PC commands. Let’s assume the PC also has a subdirectory LOGI and that we’ve downloaded logibone_r1_blink.bit to that directory. Let’s change to the PC’s LOGI directory:
PC$ cd ~/LOGI
- You are now ready to transfer logibone_r1_blink.bit from the PC to BBone. Use scp (secure copy) which in turn uses ssh for data transfers and authentication. Here’s the PC command:
PC$ scp logibone_r1_blink.bit firstname.lastname@example.org:LOGI/.
This copies logibone_r1_blink.bit from the current PC directory to ~george/LOGI on BBone, keeping the same file name. scp will ask for george’s password to authenticate the transfer.
- On BBone, make sure the file arrived by listing LOGI’s .bit files:
BBone$ ls -l *.bit
Spartan-6 LX9 .bit files are approximately 340KB.
- The last step is to write logibone_r1_blink.bit to LOGI-Bone’s FPGA. One simple way to do this is using dd on BBone:
BBone$ sudo dd if=logibone_r1_blink.bit of=/dev/logibone bs=4M
The output file is LOGI-Bone’s device driver from ValentF(x), and bs=4M makes sure the bitstream is written as a single block transfer. The permissions on /dev/logibone require superuser privileges. sudo may ask you to enter george’s password.
- If the transfer is successful, you should see a pretty blinking pattern on LOGI-Bone’s LED1 and LED0.
If you look carefully, you will also see that LOGI-Bone’s Done LED is on. It’s between the Pmod™ connectors. The LED turns on very faintly for logibone_r1_blink.bit. This is because it’s pulled up by a weak FPGA resistor instead of being driven high by a transistor.
- When you are done playing with BBone, be sure to shut it down properly so you don’t corrupt the file system:
BBone$ sudo shutdown -h now
Experiment 2: Creating and Downloading a New Bitstream
In this experiment, I create a new bitstream using Xilinx tools and download it to LOGI-Bone using the same procedure as Experiment 1. I’m not going to tell you how to install or use the Xilinx tools since that’s a long procedure and can be found elsewhere, for example at the Logi-Bone Quick Start Guide.
Experiment 2 creates a 4-bit binary counter that displays its two LSbs using LOGI-Bone LEDs and its two MSbs using external LEDs driven by two Pmod pins. The 4-bit counter is easy. The difficult part is dividing LOGI-Bone’s 50 MHz oscillator down to a value visible by humans, in this case 4 Hz.
Here’s the Verilog code for the clock generator. Instead of dividing by 12,500,000 using a single 24-bit counter, I first divide by 1000 using a 10-bit counter and then divide by 12,500 using a 14-bit counter.
module ClockDiv(Mclk, clk4Hz);
input Mclk; // 50 MHz master clock.
output clk4Hz; // 4 Hz clock-enable pulse.
reg [9:0] P; // Divide by 1000 prescaler.
wire [10:0] nextP = P + 1;
wire Pcarry = nextP; // Prescaler carry out, pulses at 50 KHz.
reg clk50KHz; // Glitch-free 50 KHz clock enable pulse.
reg [13:0] Q; // Divide by 12,500 counter.
wire [14:0] nextQ = Q + clk50KHz;
wire Qcarry = nextQ; // Low-freq carry out, pulses at 4 Hz.
always @(posedge Mclk)
// Divide by 1000: when nextP has carry out, set
// P = -1000 = 1024-1000 = 24. Pcarry is sync reset.
if (Pcarry) P <= 10'd24; else P <= nextP[9:0];
clk50KHz <= Pcarry;
// Divide by 12,500: when nextQ has carry out, set
// Q = -12,500 = 16,384-12,500 = 3,884. Qcarry is sync reset.
if (Qcarry) Q <= 14'd3884; else Q <= nextQ[13:0];
clk4Hz <= Qcarry;
This is a rather unusual way to express counters, but maps well to Xilinx logic. People usually make a divide-by-n counter by resetting it to 0 and then detecting when it reaches n-1. However, this requires logic to compare to n-1. So instead, we preset the counter to −n and increment it until it reaches all ones, which we detect using the carry out of the counter’s adder chain.
Now that we have a 4 Hz pulse stream, it’s easy to make the 4-bit counter:
module UpCounter(Mclk, reset, up, K);
input Mclk; // 50 MHz master clock.
input reset; // Asynchronous reset.
input up; // Counter enable.
output [3:0] K; // 4-bit counter;
reg [3:0] K;
wire clk4Hz; // 4 Hz demo clock enable pulse.
wire [4:0] nextK = K + up;
ClockDiv cd(Mclk, clk4Hz); // Instance of ClockDiv module.
always @(posedge Mclk or posedge reset)
if (reset) K <= 0; else if (clk4Hz) K <= nextK[3:0];
The counter includes asynchronous reset which we’ll connect to LOGI-Bone’s PB0, and an enable input which we’ll connect to PB1. Normally the counter increments at 4 Hz. If you press PB0, the counter resets to 0 and stays there. If you press PB1, the counter holds its current value.
Finally, here’s the root module that connects counter bits K[3:0] to the LEDs and connects PB0 and PB1 with the proper polarities:
module UpCountBone(Mclk, PB0, PB1, LED0, LED1, LED2, LED3);
input Mclk; // 50 MHz master clock.
input PB0; // Press to reset = active-low.
input PB1; // Press to hold = active-high enable.
output LED0, LED1; // LSbs are active high.
output LED3, LED2; // MSbs are active low.
wire [3:0] K; // 4-bit counter;
UpCounter uc(Mclk, !PB0 /*reset*/, PB1 /*up*/, K);
assign LED0 = K;
assign LED1 = K;
assign LED2 = !K;
assign LED3 = !K;
Now that we have the Verilog code for Experiment 2, we can compile it using Xilinx ISE (Integrated Software Environment). I’m using the ISE 12.4 free-as-in-beer WebPACK Editon on Ubuntu 12.04 LTS, which mostly works except for some graphical tools I don’t need. I’ve created an ISE project named LOGIdemo in LOGI, so the many files ISE generates -- including the bitstream -- will be in LOGI/LOGIdemo.
The design synthesizes without any errors or warnings on ISE 12.4. It may generate warnings in other versions.
Now, before implementing the design you need to tell ISE how to assign signals to pins. There’s a graphical tool to do this in ISE, but IMO it’s a lot easier to create and edit a User Constraint File. The name of the UCF normally matches the root module’s name, so here’s UpCountBone.ucf:
NET Mclk LOC="P85" | IOSTANDARD=LVTTL | PERIOD=20ns;
# Note: PB0 and PB1 are swapped in the R1.0 schematics, sheet 6.
NET PB0 LOC="P59" | IOSTANDARD=LVTTL; # PB0 = press to reset
NET PB1 LOC="P83" | IOSTANDARD=LVTTL; # PB1 = press to hold
NET LED0 LOC="P74" | IOSTANDARD=LVTTL; # LED0
NET LED1 LOC="P140" | IOSTANDARD=LVTTL; # LED1
NET LED2 LOC="P112" | IOSTANDARD=LVTTL; # PMOD1-1
NET LED3 LOC="P111" | IOSTANDARD=LVTTL; # PMOD1-2
I found the pin numbers in the LOGI-Bone R1.0 schematics. The LOGI-Bone Quick Start Guide shows you how to find them. I had to swap PB0 and PB1 pin numbers due to a minor error in the 5/27/2014 LOGI-Bone R1.0 schematics.
Once I have added UpCountBone.ucf to root module UpCountBone using ISE’s Add Source command, I can run the ISE Implementation tools. This takes less than a minute on my PC. There should be no errors and no significant warnings.
When placement and routing is done, I recommend checking the Pinout Report to make sure the pins agree with UpCountBone.ucf.
The last step is to generate the bitstream. The default options are mostly OK, but we’re going to set the Drive Done option so the Done LED is more visible. Watch the ISE console log to see when it’s done generating the bitstream.
When ISE is done, we can copy UpCountBone.bit to BBone and LOGI-Bone. This is basically the same as steps 7-11 in Experiment 1:
- On the PC, change to the directory that contains UpCountBone.bit, in my case LOGI/LOGIdemo.
PC$ cd ~/LOGI/LOGIdemo
- Transfer UpCountBone.bit from the PC to BBone using scp:
PC$ scp UpCountBone.bit email@example.com:LOGI/.
- On BBone, make sure the file arrived by listing LOGI’s .bit files:
BBone$ ls -l *.bit
- Write UpCountBone.bit to LOGI-Bone’s FPGA using dd:
BBone$ sudo dd if=UpCountBone.bit of=/dev/logibone bs=4M
- If the transfer is successful, you should see a binary counting pattern on LED1 and LED0. If you attach LEDs to PMOD1 pins 1 and 2 you get the two MSbs of the 4-bit counter. These are active-low LEDs, so connect their cathodes to PMOD1 pins and their anodes to +3.3V (PMOD1 pin 6) through suitable resistors, e.g., 560Ω.
If you push PB0, the counter resets to 0000. If you push PB1, the counter holds its current value.
You should also clearly see the Done LED, since it’s now driven high by an FPGA transistor.
The Experiment 2 source files LOGIdemo.v and UpCountBone.ucf are available in LOGIdemo.zip, along with UpCountBone.bit.
This was my first experience with LOGI-Bone and it went very smoothly. The board is well-designed and well-made, and provides many useful capabilities. Since I’ve done a lot of designs with other FPGAs and I’ve used ISE a lot, I had more trouble learning to use ssh and scp than the FPGA-specific tasks.
This is a simple introduction to using LOGI-Bone, intended to help you see results with minimal effort and frustration. LOGI-Bone is a very powerful board, capable of myriad interesting projects. I plan to show a few of these in upcoming ’blogs in this series.
[This document is licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported License. To view a copy of this license, visit creativecommons.org/licenses/by-sa/3.0/. No warranty is expressed or implied.]