Skip navigation
2014

Hardware description languages (HDLs) are a category of programming languages that target digital hardware design. These languages provides special features to design sequential logic( the system evolve over time represented by a clock) or combinational logic (the system output is a direct function of its input). While these language have proved to be efficient to design hardware, they often lack the tool support (editors are far behind what you can get to edit C/java/etc) and the syntax can be hard to master. More-over, these language can generate sub-optimal, faulty hardware which can be very difficult to debug.

 

Over the past-year some alternative languages have arisen to address the main issues of the more popular HDLs (VHDL/Verilog). These new languages can be classified into two categories as follows.

 

Categories of Hardware description Languages (HDLs)

 

  1. HLS (High Level Synthesis) : HLS tools, try to take an existing programming language as an input and generate the corresponding HDL (hardware description language).. Some of these tools are quite popular in the EDA industry such as CatapultC from Mentor Graphics, Matlab HDL coder, but are very expensive. Xilinx recently integrated the support of SystemC and C in their Vivado toolchain but it only supports high-end FPGA.
  2. Alternative syntax : Some tools propose an alternative syntax to VHDL or Verilog. The alternative syntax approach keeps the control of the generated hardware, but gives the advantage of an easier to master syntax and sometimes of ease of debugging.

 

While the HLS seems attractive. there is a good chance it will generate sub-optimal hardware if the designer does not write the “software” with hardware in mind. The approach is a bit magical as you can take existing C/Matlab software and generate hardware in a few clicks.

HLS is very practical to reduce time to first prototype (especially with Matlab) and for people with little (or no) HDL knowledge to produce a functional hardware design.  However,  HLS tools are not good for the users who want to learn digital design and the good HLS tools are usually very expensive (a CatapultC license can cost more than 100k$ [link], and Matlab HDL coder starts at 10k$ [link]).

Over the past year some open-source, free to use alternatives to HDL have emerged. These tools do not pretend to create hardware from behavioral description, but propose to smoothen the learning curve for digital logic design by relying on easier to master syntax and feature rich tools.

In the following we will review two of these alternatives languages (myHDL, PSHDL). To test the languages, we will use them to design and debug a simple PWM module. We chose these two languages based on their distinct properties and community adoption but other tools such as MiGen (python based syntax) which will not be covered here, but use the same kind of design flow.

Category 1 - myHDL [http://www.myhdl.org/]

 

myHDL uses python to design and test hardware components. A hardware component is designed as a python function whose arguments are the inputs and outputs of the component. The component can then describe sub-functions and designate them as combinational or sequential logic using a decorator (some text prefixed by the @ symbol that defines properties for a function/method). Once the design is complete, it can be exported to HDL (VHDL or Verilog) using a small python snippet. The design can also be tested/simulated in the python environment and generate waveform traces.

myhdl_flow.png

Installation of myHDL

Installing myHDL is straightforward and can be done with a single line on a Linux system(not tested with windows).

sudo pip install myhdl

Design of the PWM module in myHDL

 

The pwm component is pretty straightforward. It has two inputs period and t_on that designate respectively the period of the pwm signal and the number of cycles that the pwm edges are triggered on. The module has two outputs: pwm_out that is the pwm signal and period_end that is asserted at the end of a period and de-asserted otherwise. Here is the corresponding myHDL code.


from myhdl import *

 

def pwm_module(period, t_on, pwm, period_end, clk):

 

    count = Signal(intbv(0)[16:])

 

    @always(clk.posedge)

    def logic():

    if count == period:

       count.next = 0

       period_end.next = 1

    else:

       count.next = count + 1

       period_end.next = 0

 

    if count > t_on:

       pwm.next = 0

    else:

       pwm.next = 1

    return logic

 

The module is evaluated/simulated using the following test-bench.

 

def TestBench():

    clk = Signal(bool(0))

    period = Signal(intbv(200)[16:])

    t_on = Signal(intbv(100)[16:])

    pwm_out = Signal(bool(0))

    period_end = Signal(bool(0))

 

    pwm_inst = pwm_module(period, t_on, pwm_out, period_end, clk)     

    @always(delay(1))

    def tb_clkgen():

            clk.next = not clk

  

    @instance

    def tb_stim():

    period = 200

    t_on = 100      

    yield delay(2)

        for ii in xrange(400):

            yield clk.negedge

            print("%3d  %s" % (now(), bin(pwm_out, 1)))

 

        raise StopSimulation

    return tb_clkgen, tb_stim, pwm_inst

 

if __name__ == '__main__':

    Simulation(TestBench()).run()

 

The Corresponding HDL code is generated by changing this line of code:

pwm_inst = pwm_module(period, t_on, pwm_out, period_end, clk)

into this line of code:

pwm_inst = toVHDL(pwm_module, period, t_on, pwm_out, period_end, clk)

and here is the resulting VHDL:

 

 

 

library IEEE;

use IEEE.std_logic_1164.all;

use IEEE.numeric_std.all;

use std.textio.all;

 

use work.pck_myhdl_081.all;

 

entity pwm_module is

    port (

        period: in unsigned(15 downto 0);

        t_on: in unsigned(15 downto 0);

        pwm: out std_logic;

        period_end: out std_logic;

        clk: in std_logic

    );

end entity pwm_module;

 

architecture MyHDL of pwm_module is

 

signal count: unsigned(15 downto 0);

begin

 

PWM_MODULE_LOGIC: process (clk) is

begin

    if rising_edge(clk) then

        if (count = period) then

                count <= to_unsigned(0, 16);

                period_end <= '1';

        else

                count <= (count + 1);

                period_end <= '0';

        end if;

        if (count > t_on) then

                pwm <= '0';

        else

                pwm <= '1';

        end if;

    end if;

end process PWM_MODULE_LOGIC;

 

end architecture MyHDL;

 

myHDL lines to VHDL lines : 20 -> 42 = 0.47

Pro and Cons of using myHDL or similar languages

 

Pro:

  • Python syntax is clean and forces the user to structure the code appropriately
  • The syntax elements introduced for hardware design are relevant and does not add much syntax (the next attribute is a great idea and reflects the hardware behavior)
  • The quality of the generated code is great !
  • The simulation has a great potential, you can even generate a waveform
  • One can take advantage of the extensive collection of Python packages to create powerful simulations
  • Small designs can fit in one file.

Cons:

  • The use of decorators is not great for readability (and i’am not a decorator fan …)
  • One really needs to understand digital logic and hardware design before starting a myHDL module
  • One really needs to master the basics of Python before getting started
  • Python will raise errors for syntax errors but simulation does raise warning or errors if there is a design error (incomplete if/case clause or other things that a synthesizer would detect)
  • There is no (that i know of) myHDL specific editor or environment that would ease the beginner experience.

Category 2 - The Custom Syntax Approach - PSDHL [http://pshdl.org/]

 

PSHDL (plain and simple hardware description language) is an HDL language with custom syntax that takes elements inherited from C/SystemC and adds a custom set of keywords and coding elements to represent a hardware module. A module has no arguments but declares some internal variables as “in” or “out”. The nice and clever thing about PSHDL is that only one keyword is used to represent a sequential part of the module. Instead of declaring a computational unit of sequential or combinational logic, a keyword “register” is used to identify the variables/signals that are to be updated in a synchronous process. This is particularly relevant because every HDL design will be translated into  LUTs, MUXs, D-latches or registers.

The PSHDL syntax is fairly easy to understand and there is not much syntactical noise. The best thing about PSHDL is that it runs in the web browser! Just like the mBED initiative (for ARM micro-controllers), the pshdl.org website, proposes to create a workspace in which you can edit, compile (to VHDL) and debug your design all on-line. This means, no tools to install (still need to install the ISE/quartus tools to synthesize), OS independent (no problem with running it under Linux/Windows.  The community is rather small up until now, but the tool deserves a try!

Creating the PWM module using PSHDL

 

Below is the PSHDL code for the pwm module:


 

module de.tuhh.ict.pwmModule {

  @clock in bit clk;

  in uint<16> period, t_on;

  out bit pwm_out, period_end;

  register(clock=clk) uint<16> counter;

  if(counter > period){

    counter = 0;

    period_end = 1 ;

  }

  else{

    counter = counter + 1;

    period_end = 0;

  }

  if(counter > t_on){

   pwm_out = 0;

  }

  else{

    pwm_out = 1;

  }

}

 

Below is the VHDL code generated by PSHDL

 

library ieee;

use ieee.std_logic_1164.all;

use ieee.numeric_std.all;

use work.Casts.ALL;

use work.ShiftOps.ALL;

use work.Types.ALL;

entity de_tuhh_ict_pwmModule is

   port (

       rst : in std_logic;

       clk : in std_logic;

       period : in unsigned(15 downto 0);

       t_on : in unsigned(15 downto 0);

       pwm_out : out std_logic;

       period_end : out std_logic

   );

end;

 

architecture pshdlGenerated of de_tuhh_ict_pwmModule is

   signal counter : unsigned(15 downto 0);

begin

   process(counter, period, t_on)

   begin

       pwm_out <= '0';

       period_end <= '0';

       if (counter > period) then

           period_end <= '1';

       else

           period_end <= '0';

       end if;

       if (counter > t_on) then

           pwm_out <= '0';

       else

           pwm_out <= '1';

       end if;

   end process;

   process(clk)

   begin

       if RISING_EDGE(clk) then

           if rst = '1' then

               counter <= (others => '0');

           else

               if (counter > period) then

                   counter <= (others => '0');

               else

                   counter <= (counter + TO_UNSIGNED(1, 16));

               end if;

           end if;

       end if;

   end process;

end;


PSHDL lines to VHDL lines : 21 -> 51 = 0.41

Pro and cons

Pros :

  • Online tool ! No installation and is OS agnostic
  • Easy to use syntax for people who know C/C++
  • Clever use of the “register” keyword to denote sequential assignments
  • Outputs nicely formatted VHDL
  • Generated VHDL interfaces easily with existing VHDL code

Cons:

  • Online tool - some people may complain that its not great for privacy and intellectual property
  • Some syntax elements like the package prefix for a module create lengthy text
  • A “register” can be associated to a clock and reset by passing arguments to it. This is misleading for C/C++ programmers as it creates a type with an argument (and not a template like the other types) which is not valid C/C++ code.
  • Simulation does not seem to be fully functional in the online tool
  • The community is small (but can grow if you give it a try)

Conclusion

 

These two alternative HDL languages/tools do a great job to ease the process of  writing and debugging HDL. They both rely on different principles.  myHDL defines combinational/sequential functions while PSHDL defines sequential signals for the sequential behavior.  This allows you to pick what works best for you! The main drawback with both of these (tools and other alternatives languages) is that they are not directly supported in the vendor tools (Quartus/ISE) and that they are not recognized as standard hardware design languages in the professional world. This means that you will still have to learn VHDL/Verilog at some point if this is part of your career plan.

 

There is no indication that FPGA vendors are willing to open the access to their synthesis tools for third parties, so for any VHDL/Verilog alternatives you will still have to install and use their tools to synthesize and create the binary files to configure the FPGA.

 

One other language that tends to emerge as a standard for hardware (and system) design is SystemC (at least with Xilinx). While myHDL does not rely on any of the SystemC concepts, PSHDL has the advantage of being (to some extend) C/C++ based.

 

To get more people to use FPGAs there is a need to propose a large diversity of languages/tools. See the diversity of languages available to program microcontrollers. Some years ago you had to use C or assembler to design embedded software, but now you can use C/C++, Arduino (C++ based), javascript, Python and more.  We need the same kind of languages competition for HDL as each new language may attract more users and create new uses for FPGAs.

 

What features do you foresee being needed for a killer hardware description language? 


Creative Commons License

This work is licensed under a Creative Commons Attribution 4.0 International License.

Abstract: This ’blog describes using a ValentF(x) LOGI-EDU board to make a 4-digit BCD (binary-coded decimal) counter using LOGI-EDU’s 4-digit seven-segment LED module.  I used both LOGI-Pi and LOGI-Bone FPGA boards to implement the BCD counter logic.

 

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.

 

This is my third ’blog about ValentF(x) LOGI boards.  To get started using LOGI FPGA boards, see my first two LOGI ’blogs First Experiments with the ValentF(x) LOGI-Bone and First Experiments with the ValentF(x) LOGI-Pi, and also the ValentF(x) Logi-Bone Quick Start Guide and LOGI-Pi Quick Start Guide.

 

The ValentF(x) LOGI-EDU is an educational expansion card for LOGI-Pi, though it can also be used with LOGI-Bone if you don’t need multiple features simultaneously.  LOGI-EDU has a number of useful I/O devices including a VGA output with up to 512 colors, a multiplexed 4-digit seven-segment display, two PS/2 ports, two Nintendo NES controller ports, and an audio output using PWM or sigma-delta modulation.  There’s also a small prototyping area.  Here’s a picture of the board from the ValentF(x) wiki, copied with permission:

LOGI-EDUsmall.jpg

LOGI-EDU is primarily for LOGI-Pi, and element14 currently only sells it as a package with a LOGI-Pi.  LOGI-EDU plugs into LOGI-Pi’s four Digilent Pmod™sockets:

LOGI-Pi-EDUsmall.jpg

The Pmods are numbered 1-4 from left to right in the photos and connect to LOGI-EDU resources as follows:

 

  • Pmod 1: VGA and +3.3V power from LOGI-Pi.
  • Pmod 2: Seven-segment display.
  • Pmod 3: Seven-segment display plus PS/2 #2 and VGA LSbs.
  • Pmod 4: PS/2 #1, NES, and PWM.

 

All four Pmods provide two ground pins.  For details on how the Pmods are connected, see the LOGI-EDU schematic.

 

You can use LOGI-EDU with LOGI-Bone, but since LOGI-Bone only has two Pmod sockets you can only use two adjacent LOGI-EDU plugs.  In this ’blog, we use the seven-segment display so we need LOGI-EDU Pmods 2 and 3.  They plug very nicely into the two LOGI-Bone sockets:

BoneEDU.jpg

All power for the LEDs comes from FPGA I/Os so we don’t need the LOGI-EDU Pmod 1 +3.3V pins.

 

The seven-segment display is a fairly common LITEON LTC-4727JS: here’s the data sheet.  The digits are numbered 1-4 from left to right, and the segments of each digit are numbered A-G in the usual way (see Wikipedia):

LEDdisplay.png

Here is part of the LOGI-EDU schematic, which shows how the display is wired up:

LEDschem.png

The LTS-4727JS is a multiplexed display [Wikipedia] to save pins, both on the display and the FPGA.  Only one digit is turned on at a time, but they are refreshed quickly enough that normal eyes see all digits displayed at once.

 

The LTS-4727JS is a common cathode display, which means that the LEDs of a digit (including decimal point DP) have their cathodes wired together.  To turn on a digit, the FPGA pulls a combination of anode signals SSEG0-A, SSEG1-B, ..., SSEG7-DP to +3.3V and also drives one digit select SEG_CTRL_A1, SEG_CTRL_A2, ..., SEG_CTRL_L high as well, setting the rest low.  The selected SEG_CTRL turns on one transistor Q1-Q5, which pulls one common cathode pin A1-A4 or L low.  This creates a current path from each high SSEG line to ground, turning on the selected segments of the selected digit.

 

Each SSEG line has a 100Ω resistor to limit current to about 10 mA.  This would usually be too bright, but in normal operation each digit is only on 1/4 of the time so 10 mA gives good brightness.  Since the selected digit’s segments including decimal point could all be on simultaneously, the combined cathode current could be as high as 80 mA.  This is why a transistor pulls the common cathode down.  An FPGA pin cannot sink that much current.

 

4-Digit BCD Counter

 

Now that we’re familiar with the display, let’s use it to make a 4-digit BCD counter with these features:

 

  • Increment every tenth of a second.
  • Display seconds and tenths of seconds in decimal from 0.0 to 999.9, wrapping every 1000 seconds.
  • Display decimal point and suppress leading zeros.
  • PB0 resets the counter to 0.0.
  • PB1 holds the counter at its current value.

 

PB0 and PB1 have the same behavior as the 4-bit binary counter in First Experiments with the ValentF(x) LOGI-Bone and First Experiments with the ValentF(x) LOGI-Pi.

 

The Verilog code for the BCD counter is in LOGIdemo.v (part of LOGIdemo.zip) along with other sample code.  Let’s take a look the Verilog modules that make up the counter, starting with SevenSeg which converts a BCD digit to its seven-segment representation:

LEDdisplay.png

module SevenSeg(X, Y);

input  [3:0] X;    // BCD digit.

output [6:0] Y;    // Seven-segment code "ABCDEFG".

 

    assign Y = X == 0? 7'b1111110: X == 1? 7'b0110000:

        X == 2? 7'b1101101: X == 3? 7'b1111001:

        X == 4? 7'b0110011: X == 5? 7'b1011011:

        X == 6? 7'b1011111: X == 7? 7'b1110000:

        X == 8? 7'b1111111: X == 9? 7'b1110011: 7'h00;

endmodule

 

Input X is a 4-bit BCD digit from 0000 to 1001.  Output Y is a 7-bit seven-segment display code ABCDEFG with MSb A and LSb G.  The body is simply a multiplexer.  Xilinx logic synthesis converts it into a ROM look-up table.

 

Module DigitCounter is a divide-by-10 counter:

 

module DigitCounter(Mclk, reset, Cin, Cout, D);

input  Mclk;       // 50 MHz master clock.

input  reset;      // Asynchronous reset.

input  Cin;        // Carry in pulse.

output Cout;       // Carry out if carry in and D = 9.

output [3:0] D;    // Current value of digit.

 

    reg        [3:0] D;    // Digit counter from 0 to 9.

 

    assign Cout = Cin && D >= 9;

    always @(posedge Mclk or posedge reset)

    if (reset) D <= 0; else if (Cin) D <= Cout? 0: D+1;

endmodule

 

Mclk is the LOGI-Pi or LOGI-Bone 50 MHz master clock.  It runs continuously.  Cin is a “carry in” pulse that is high for one 20 ns clock cycle to increment the 4-bit counter.  Cout is a “carry out” pulse that occurs when Cin is high and the current count D is 9 or more: Cout clears D to 0.  D should never exceed 9, but “D >= 9” gets us out of a bad state quicker if D is ever reset to 10-15.  D is a module output so we can display it.  Finally, there’s an asynchronous reset to force D to zero immediately if you press PB0.

 

Module ClockDiv2K generates a single-cycle LEDclk pulse every 500 ms (2 KHz):

 

// Divide 50 MHz master clock by 25,000 to get 2 KHz LED

// multiplexer clock.

module ClockDiv2K(Mclk, LEDclk);

input  Mclk;        // 50 MHz master clock.

output LEDclk;      // 2 KHz LED mux clock (clock-enable pulses).

reg    LEDclk;

 

    reg  [14:0] Q;            // Divide by 25,000 counter.

    wire [15:0] nextQ = Q + 1;

    wire Qcarry = nextQ[15];  // Carry out, pulses at 2 KHz.

 

    always @(posedge Mclk)

    begin

        // Divide by 25,000: when nextQ has carry out,

        // set Q = -25,000 = 32,768-25,000 = 7,768.

        // Qcarry is sync reset.

        if (Qcarry) Q <= 15'd7768; else Q <= nextQ[14:0];

        LEDclk <= Qcarry;

    end

endmodule

 

This counter uses the same technique as module ClockDiv in First Experiments with the ValentF(x) LOGI-Bone and First Experiments with the ValentF(x) LOGI-Pi.  This is a rather unusual way to express a counter, but it 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, as we did with DigitCounter.  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 all the submodules, here’s the root module SevenSegDemo.  First let’s take care of declaring the I/O pins and converting active-low PB0 to active-high reset:

 

module SevenSegDemo(Mclk, PB0, PB1, Y, dp, en1, en2, en3, en4);

input  Mclk;      // 50 MHz master clock.

input  PB0;       // Press to reset = active-low.

input  PB1;       // Press to hold = active-high enable.

output [6:0] Y;   // Seven-segment code "ABCDEFG".

output dp;        // Turn on decimal point for digit 3.

output en1, en2;  // Enables for digits 1-4 (left to right).

output en3, en4;

 

    wire reset = !PB0;    // PB0 is active-low.

 

Next we need a divide-by-200 counter JK to convert the 2 KHz LEDclk produced by ClockDiv2K into a 10 Hz carry into the tenths digit.

 

wire LEDclk;      // 2 KHz LED mux clock (clock-enable pulses).

reg  [1:0] K;     // Counter LSbs;

reg  [5:0] J;     // Counter MSbs.

wire [6:0] nextJ = J + (LEDclk && K == 3 && PB1);

wire resetJ = reset || nextJ[6];   // Synchronous reset.

 

Counter JK comes in two parts.  The MSbs J[5:0] are a divide-by-50 counter which is reset by PB0 and held if you press PB1.  The LSbs K[1:0] select a digit for LED multiplexing.  K must increment continuously since multiplexing still needs to occur when pressing PB0 or PB1.  K simply increments whenever LEDclk occurs (see below).  J increments when K overflows and PB1 is not pressed, i.e., counting is enabled.  J uses the same divide-by-n logic style as ClockDiv2K.

 

Here are the rest of the signal declarations.  c1-c4 are the carries into digits 1 (MSD) through 4 (LSD).  c4 is the carry out from counter JK.

 

wire c4 = nextJ[6];  // Carry into digit 4 (tenths).

wire c1, c2, c3;     // Carry into digit 1-3.

wire dummy;          // Carry out of digit 1 (unused).

wire [15:0] D;       // Values of digits 1-4.

wire [3:0] Dsel;     // Digit selected by K.

 

Here the instance of ClockDiv2K, followed by the logic to update counter JK:

 

ClockDiv2K cd(Mclk, LEDclk);

 

always @(posedge Mclk)

begin

    // Always increment JK counter LSbs since they multiplex the digits.

    if (LEDclk) K <= K+1;

    // Reset JK counter MSbs if PB0 to get 500us reset response.

    // Divide J by 50: when nextJ has carry out, set J = -50 = 64-50 = 14.

    if (resetJ) J <= 6'd14; else J <= nextJ[5:0];

end

 

Next we have four instances of DigitCounter, one for each digit.  The carry out of each digit is the carry in of the next higher digit.  The four 4-bit digit values are combined into a 16-bit signal D[15:0].

 

// Digit counters for digits 1-4, starting with digit 4.

DigitCounter dc4(Mclk, reset, c4, c3, D[3:0]);       // tenths

DigitCounter dc3(Mclk, reset, c3, c2, D[7:4]);       // seconds

DigitCounter dc2(Mclk, reset, c2, c1, D[11:8]);      // tens

DigitCounter dc1(Mclk, reset, c1, dummy, D[15:12]);  // hundreds

 

// Select a digit using K.

assign Dsel = K == 0? D[3:0]: K == 1? D[7:4]: K == 2? D[11:8]: D[15:12];

 

Dsel is the digit of D[15:0] selected by K using a multiplexer.  Module SevenSeg converts it to seven-segment code Y:

 

SevenSeg ss(Dsel, Y);

 

The decimal point is a special case: it’s turned on if we’re doing digit 3 (K = 1):

 

assign dp = K == 1;

 

The final logic enables each digit, according to the value of K.  Digits 3 and 4 are always shown, so we just need to check K.  Digits 1 and 2 are more interesting because we suppress leading zeros:

 

assign en4 = K == 0;    // Always show digit 4.

assign en3 = K == 1;    // Always show digit 3.

// Do not show d2 if digits 1 and 2 are both 0.

assign en2 = K == 2 && D[15:8] != 0;

// Do not show d1 if it's 0.

assign en1 = K == 3 && D[15:12] != 0;

endmodule

 

Running Xilinx ISE

 

Now that we have the Verilog code, 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 directory LOGI, so the many files ISE generates -- including the bitstream -- will be in LOGI/LOGIdemo.

 

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 Logi-Pi Quick Start Guide.  Gadget Factory also has some tutorials: Install ISE WebPack and Papilio Xilinx ISE WebPack VHDL Getting Started.

 

SevenSegDemo synthesizes without any errors on ISE 12.4 and the warnings are reasonable.  One of the hardest tasks for a new ISE user is learning which warnings can be ignored and which are important.

 

Now, before implementing the design you need to tell ISE how to assign signals to pins.  This is fairly tedious for LOGI-EDU, because you must figure out how seven-segment display pins connect to LOGI-EDU Pmod pins using the LOGI-EDU schematic, and then use the LOGI-Pi and/or LOGI-Bone schematics to see how their Pmod pins connect to their FPGA pins.  LOGI-Bone has the added complication that we’re plugging LOGI-EDU Pmods 2 and 3 into LOGI-Bone Pmods 1 and 2.

 

There’s a graphical tool for assigning pins in ISE, but IMO it’s a lot easier to create and edit a User Constraint File (UCF).  For this ’blog I created two versions of the UCF, one for LOGI-Pi and one for LOGI-Bone.  Here’s SevenSegPi.ucf for LOGI-Pi:

 

NET Mclk  LOC="P85"  | PERIOD=20ns;

NET PB0   LOC="P102";    # PB0 = press to reset

NET PB1   LOC="P101";    # PB1 = press to hold

# PMOD2

NET en2   LOC="P142";    # PMOD2-1

#NET enL  LOC="P141";    # PMOD2-2

NET en3   LOC="P15";     # PMOD2-3

NET en4   LOC="P14";     # PMOD2-4

NET en1   LOC="P144";    # PMOD2-7

NET Y<3>  LOC="P143";    # PMOD2-8

NET Y<2>  LOC="P140";    # PMOD2-9

NET dp    LOC="P139";    # PMOD2-10

# PMOD3

NET Y<0>  LOC="P138";    # PMOD3-1

NET Y<4>  LOC="P137";    # PMOD3-2

#NET xxx  LOC="P124";    # PMOD3-3

#NET xxx  LOC="P123";    # PMOD3-4

NET Y<5>  LOC="P119";    # PMOD3-7

NET Y<6>  LOC="P118";    # PMOD3-8

NET Y<1>  LOC="P117";    # PMOD3-9

#NET xxx  LOC="P116";    # PMOD3-10

 

Here’s SevenSegBone.ucf for LOGI-Bone:

 

NET Mclk  LOC="P85"  | PERIOD=20ns;

# Note: PB0 and PB1 are swapped in the R1.0 schematics, sheet 6.

NET PB0   LOC="P59";     # PB0 = press to reset

NET PB1   LOC="P83";     # PB1 = press to hold

# Use LOGI-Bone PMOD1 to talk to LOGI-EDU PMOD2.

NET en2   LOC="P112";    # PMOD1-1

#NET enL  LOC="P111";    # PMOD1-2

NET en3   LOC="P67";     # PMOD1-3

NET en4   LOC="P66";     # PMOD1-4

NET en1   LOC="P62";     # PMOD1-7

NET Y<3>  LOC="P61";     # PMOD1-8

NET Y<2>  LOC="P58";     # PMOD1-9

NET dp    LOC="P57";     # PMOD1-10

# Use LOGI-Bone PMOD2 to talk to LOGI-EDU PMOD3.

NET Y<0>  LOC="P56";     # PMOD2-1

NET Y<4>  LOC="P55";     # PMOD2-2

#NET xxx  LOC="P46";     # PMOD2-3

#NET xxx  LOC="P45";     # PMOD2-4

NET Y<5>  LOC="P48";     # PMOD2-7

NET Y<6>  LOC="P47";     # PMOD2-8

NET Y<1>  LOC="P44";     # PMOD2-9

#NET xxx  LOC="P43";     # PMOD2-10

 

Note that the pin numbers are completely different from LOGI-Pi except for Mclk.

 

Attach SevenSegPi.ucf or SevenSegBone.ucf -- whichever matches your LOGI FPGA board -- to root module SevenSegDemo using ISE’s Add Source command.  Then run the ISE Implementation tools.  This takes about 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 the UCF file.

 

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, copy SevenSegDemo.bit to Raspberry Pi and LOGI-Pi, or to BeagleBone and LOGI-Bone.  This is described in First Experiments with the ValentF(x) LOGI-Bone and First Experiments with the ValentF(x) LOGI-Pi.  When the transfer is successful, you’ll see the LED display start counting merrily from 0.0 to 999.9, and repeat.  If you push PB0, the counter resets to 0.0.  If you push PB1, the counter holds its current value.

 

The Seven-Segment BCD Counter source files LOGIdemo.v and UCFs are available in LOGIdemo.zip, along with SevenSegPi.bit and SevenSegBone.bit which are renamed copies of SevenSegDemo.bit implemented for LOGI-Pi and LOGI-Bone.

 

Conclusion

 

This was my first experience with LOGI-EDU and it went very smoothly.  The board is well-designed and well-made, and provides many useful capabilities.  I did have to cut a small notch in the front panel of my home-made open-frame RasPi case so that I could plug in LOGI-EDU.  With four Pmod connectors it’s hard to push LOGI-EDU and LOGI-Pi together and even harder to pull them apart.  Using various size screwdrivers as levers worked well.  It’s much easier with the LOGI-Bone since there are only two Pmod connectors.

 

This is a simple introduction to using LOGI-EDU, and only plays with the seven-segment LED display.  There are lots of other interesting projects, especially with the VGA output.  I’m looking forward to playing with VGA when I get a chance.

 

[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.  Raspberry Pi is a trademark of the Raspberry Pi Foundation.]

Introduction


In a previous blog post ValentF(x) gave an explanation of what FPGAs (field programmable gate arrays) are and how they are a very valuable resource when designing electronics systems.  The article went on to describe the major differences in the way FPGAs operate from CPU/MCU technology.  Finally, it was highlighted that FPGAs, especially when used in conjunction with CPU technology, are a powerful tool with both having their own respective strong points in how they process data.  

 

This blog article focuses on how a user should begin to look at using an FPGA in conjunction with a CPU using a co-processing system.  The user will better understand how the system is  designed to handle processing multiple tasks, scheduling, mapping of the processing tasks and the intercommunication between the LOGI FPGA boards and the host CPU or MCU.

 

This article will use examples from the LOGI Face project, which is an open source animatronics robot project as the basis for discussing the co-processing methodologies.  We will be using real examples from the LOGI projects.  Additionally we will refer the user to the LOGI Face Lite project which is a more basic version of LOGI Face that the user can fully replicated with 3D printable parts and off-the-shelf components.  The LOGI Face Lite wiki page contains instructions to build and run the algorithms in the project. 


What is Hardware/Software Co-design ?


Co-design consists of designing an electronics system as a mixture of software and hardware components. Software components usually run on processors such as a CPU, DSP or GPU, where hardware components run on an FPGA or a dedicated ASIC (application specific integrated circuit). This kind of design method is used to take advantage of the inherent parallelism between the tasks of the application and ease of re-use between applications.

 

Steps for Designing a Hardware/Software Co-processing System

 

  • Partition the application into the hardware and software components
  • Map the software components to the CPU resources
  • Map the needed custom hardware components to the FPGA resources
  • Schedule the software components
  • Manage the communications between the software and hardware components

 

These steps can either be performed by co-design tools, or by hand, based on the knowledge of the designer. In the following we will describe how the LOGI Pi can be used to perform such a co-design in run real-time control oriented applications or high performance applications with the Raspberry Pi.

Communication between the LOGI Pi and Raspberry Pi


A critical requirement of a co-design system is the method of communication between the FPGA and CPU processing units of the platform.  The processing units in this case are the LOGI FPGA and the Raspberry Pi.  The LOGI projects use the wishbone bus to ensure fast, reliable and expandable communication between the hardware and software components. The Raspberry Pi does not provide a wishbone bus on its expansion, so it was required to take advantage of the SPI port and to design a hardware “wrapper” component  in the FPGA that transforms the SPI serial bus into a 16 bit wishbone master component. The use of this bus allows users to take advantage of the extensive repository of open-source HDL components hosted on open-cores.org and other shared HDL locations.

To handle the communication on the SPI bus each transaction is composed of the following information.

1) set slave select low 2) send a 16 bit command word with bits 15 to 2 being the address of the access, bit 1 to indicate burst mode (1) , and bit 0 to indicate read (1) or write (0) (see figure).3) send/receive 16 bit words to/from the address set in the first transaction. If burst mode is set, the address will be increased on each subsequent access until the chip select line is set to high (end of transaction). 4) set slave select high

Such transactions allow users to take advantage of the integrated SPI controller of the Raspberry Pi which uses a 4096 byte fifo. This access format permits the following useful bandwidth to be reached (the 2 bit of synchro is transfer overhead on the SPI bus):

  • For a single 16 bit access :(16 bit data)/(2 bit synchro + 16 bit command + 16 bit data) => 47% of the theoretical bandwidth.
  • For a 4094 byte access : ( 2047 * (16 bit data))/(2 bit synchro + 16 bit command + 2047 * (16 bit data) 99.7% of the theoretical bandwidth.

 

This means that for most control based applications (writing/reading registers), we get half of the theoretical bandwidth, but for data based applications, such as writing and reading to buffers or memory, the performance is 99% of the theoretical bandwidth. It could be argued that getting rid of the wishbone interface and replacing it with an application specific data communication protocol (formatted packet of data) on the SPI bus could give the maximum bandwidth, but this would break the generic approach that is proposed here. The communication is abstracted using a dedicated C API that provides memory read and write functions.  ValentF(x) also provides a library of hardware components (VHDL) that the user can integrate into designs (servo controller, pwm controller, fifo controller, pid controller …).

Communication between the LOGI Bone and BeagleBone


The BeagleBone exposes an external memory bus (called GPMC General on its P8 and P9 expansion connectors. This memory bus, provides 16-bit multiplexed address/data, 3 chip select, read, write, clock, address latch, high-byte/low-byte signals.The bus behavior is configured through the device-tree on the linux system as a synchronous bus with 50Mhz clock. This bus is theoretically capable of achieving 80MB/s but current settings limit the bus speed to a maximum of 20MB/s read, 27MB/s write. Higher speeds (50MB/s) can be achieved by enabling burst access (requires to re-compile the kernel) but this breaks the support for some of the IPs (mainly wishbone_fifo). Even higher speeds were measured by switching the bus to asynchronous mode and disabling DMA, but the data transfers would then increase the CPU load quite a lot.

On the FPGA side, ValentF(x) provides a wishbone wrapper that transforms this bus protocol into a wishbone master compatible with the LOGI drivers. On the Linux system side a kernel module is loaded and is in charge of triggering DMA transfers for each user request. The driver exposes a LOGI Bone_mem char device in the “/dev” directory that can be accessed through open/read/write/close functions in C or directly using dd from the command line.

This communication is also abstracted using a dedicated C API that provides memory read/write functions. This C API standardizes function accesses for the LOGI Bone and LOGI Pi thus enabling code for the LOGI Bone to be ported to the LOGI Pi with no modification.

Abstracting the communication layer using Python


Because the Raspberry Pi platform is targeted toward education, it was decided to offer the option to abstract the communication over the SPI bus using a Python library that provides easy access function calls to the LOGI Pi and LOGI Bone platforms. The communication package also comes with a Hardware Abstraction Library (HAL) that provides Python support for most of the hardware modules of the LOGI hardware library.  LOGI HAL, which is part of the LOGI Stack, gives easy access to the wishbone hardware modules by providing direct read and write access commands to the modules.  The HAL drivers will be extended as the module base grows.

A Basic Example of Hardware/Software Co-design with LOGI Face


LOGI Face is a demonstration based on the LOGI Pi platform that acts as a telepresence animatronic device. The LOGI Face demo includes software and hardware functionality using the Raspberry Pi and the LOGI Pi FPGA in a co-design architecture. 

LOGI Face Software


The software consists of a VOIP (voice over internet protocol) client, text to voice synthesizer library and LOGI Tools which consist of C SPI drivers and Python language wrappers that give easy and direct communication to the wishbone devices on the FPGA. Using a VOIP client allows communication to and from LOGI Face from any internet connected VOIP clients, giving access to anyone on the internet access to sending commands and data to LOGI face which are communicated to the FPGA to control the hardware components.  The software parses the commands and data and tagged subsets of data are then synthesized to speech using the espeak text to voice library.   Users can also use the linphone VOIP client to bi-directionally communicate with voice through LOGI Face.  The remote voice is broadcasted and heard on installed speaker in LOGI Face and the local user can then speak back to the remote user using the installed microphone in LOGI Face. 

LOGI Face Hardware

The FPGA hardware side implementation consists of a SPI to wishbone wrapper, wishbone hardware modules including servos(mouth and eyebrows), RGB LEDs (hair color), 8x8 LED matrix (eyes) and SPI ADC drivers.  The wishbone wrapper acts as glue logic that converts the SPI data to the wishbone protocol.  The servos are used to emulate emotion by controlling the mouth which smiles or frowns and the eyebrows are likewise used to show emotions.  A diagram depicting the tasks for the application can be seen in the following diagram.

logiface-diagram.png

LOGI Face Tasks


The LOGI Face applications tasks are partitioned on the LOGI Pi platform with software components running on the Raspberry Pi and hardware components on the LOGI Pi. The choice of software components was made to take advantage of existing software libraries including the espeak text to speech engine and linphone SIP client. The hardware components are time critical tasks including the wishbone wrapper, servo drivers, led matrix controller, SPI ADC controller and PWM controller.

Further work on this co-processing system could include optimizing CPU performance by moving parts of the espeak TTS (text to speech) engine and other software tasks to hardware in the FPGA. Moving software to the FPGA is a good example that showcases the flexibility and power of using an FPGA with an CPU.

A diagram with the final co-processing tasks of the LOGI Face application can be see in the following diagram.

 

LOGI Face Lite

 

LOGI Face Lite is a simplified version of the above mentioned LOGI Face project.   The LOGI Face Lite project was created to allow direct access to the main hardware components on LOGI Face.  LOGI Face Lite is intended to allow users to quickly build and replicate the basic software and hardware co-processing functions including servo, SPI ADC, PWM RGB LED and 8x8 Matrix LEDs.  Each component has an HDL hardware implementation on the FPGA and function API call access from the Raspberry Pi.  We hope that this give users a feel for how they might go about designing a project using the Raspberry Pi or BeagleBone and the LOGI FPGA boards. 

Note that the lite version has removed the VOIP Lin client and text to speech functionality to give users a more direct interface to the hardware components using a simple python script.  We hope this that will make it easier to understand and begin working with the components and that when the user is ready will move to the full LOGI Face project with all of the features.

Diagram of wiring and functions

3D model of frame and components

Assembled LOGI Face Lite


FPGA Control

  • 2x Servos to control the eyebrows - mad , happy, angry, surprised, etc.
  • 2x Servos to control mouth - smile, frown, etc
  • 1x RGB LEDs which control the hair color, correspond to mood, sounds, etc
  • 2 x 8x8 LED matrices which display animated eyes - blink, look up/down or side to side, etc
  • SPI microphone connected ADC to collect ambient sounds which are used to dynamically add responses to LOGI Face

 

Software ControlEach of the FPGA controllers is accessible to send and receive data from on the Raspberry Pi.  A basic example Python program is supplied which shows how to directly access the FPGA hardware components from the Raspberry Pi.


Build the HDL using the Skeleton EditorAs an exercise the users can use LOGI Skeleton Editor to generate the LOGI Face Lite hardware project, which can then be synthesized and loaded into the FPGA.  A Json file can be downloaded from the wiki can can then be imported into the Skeleton Editor, which will then configure the HDL project the user.  The user can then  use the generated HDL from Skeleton Editor to synthesize and generate a bitstream from Xilinx ISE. Alternatively we supply a pre-built bitsream to configure the FPGA.


Re-create the ProjectWe encourage users to go to  the LOGI Face Lite ValentF(x) wiki page for a walk through on how to build the mechanical assembly with a 3D printable frame, parts list for required parts and instructions to configure the Skeleton project, build the hardware and finally run the software. 


http://valentfx.com/wiki/index.php?title=LOGI_Face_Lite_-_Project


You can also jump to any of these resources the project

Conclusion


The LOGI Pi and LOGI Bone were designed to develop co-designed applications in a low cost tightly coupled FPGA/processor package. On the Raspberry Pi or BeagleBone the ARM processor has plenty of computing power while the Spartan 6 LX9 FPGA provides enough logic for many types of applications that would not otherwise be available with a standalone processor.

 

A FPGA and processor platform allows users to progressively migrate pieces of an application to hardware to gain performance while an FPGA only platform can require a lot of work to get simple tasks that processors are very good at. Using languages such as Python on the Raspberry Pi or BeagleBone enables users to quickly connect to a variety of library or web services and the FPGA can act as a proxy to sensors and actuators, taking care of all low-level real-time signal generation and processing. The LOGI Face project can easily be augmented with functions such as broadcasting the weather or  reading  tweets, emails or text messages by using the many available libraries of Python.  The hardware architecture can be extended to provide more actuators or perform more advanced processing on the sound input such as FFT, knock detection and other interesting applications.

 

We hope to hear from you about what kind of projects you would like to see and or how we might improve our current projects. 

 

References

http://espeak.sourceforge.net/

http://www.linphone.org/technical-corner/liblinphone/overview

https://github.com/jpiat/hard-cv

https://github.com/fpga-logi/logi-projects

https://github.com/fpga-logi/logi-hard

http://valentfx.com/wiki/index.php?title=LOGI_Face_Lite_-_Project


Creative Commons License

This work is licensed to ValentF(x) under a Creative Commons Attribution 4.0 International License.

Abstract:  This ’blog describes my first experiments using a ValentF(x) LOGI-Pi FPGA board.  After a short overview of LOGI-Pi 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-Bone version of this ’blog, see First Experiments with the ValentF(x) LOGI-Bone.


The ValentF(x) LOGI-Pi is a new FPGA development board for the Raspberry Pi Models A, B, and B+.  Its chief advantage over other FPGA boards is that RasPi GPIO pins connect directly to the FPGA so you have a flexible high-speed, low-latency connection.  LOGI-Pi also has expansion sockets compatible with 3.3V Arduino UNO, DUE, and DUEM shields as well as four 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-Pi, from ValentF(x)’s LOGI-Pi User Guide, copied with permission:

 

LOGI-PiPCBrev1.png

In addition to the FPGA and expansion sockets LOGI-Pi 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-Pi 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-Pi but do not plug into RasPi 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-Pi’s FPGA.  By default, RasPi writes the bitstream by running logi_loader, which uses SPI to transfer the bitstream’s data bits and some GPIO pins 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 RasPi -- is treating the FPGA as a slave device.

 

You can modify LOGI-Pi 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-Pi application that only uses RasPi 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-Pi.  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-Pi if you don’t have a RasPi.

 

In this ’blog we will be using the default Slave Serial mode with RasPi writing the bitstream.

 

Installing and Powering LOGI-Pi

 

LOGI-Pi is designed to plug directly onto a RasPi Model A or B Expansion header P1, as shown in this photo from FPGA Development Board for the RASPBERRY PI.


5ddff50ca289a4954a4b508a95780218.png


The two boards are aligned except for a small LOGI-Pi overhang on the RasPi HDMI side.

 

LOGI-Pi is best suited to the RasPi Model A/B rev 2.0 PCB which has alignment holes in the same positions as LOGI-Pi mounting holes so you can screw the two boards together with nylon standoffs and screws (provided).  LOGI-Pi also plugs into a RasPi 1.0 PCB just fine, but the 1.0 PCB doesn’t have alignment holes so you don’t get the standoffs’ mechanical security.  LOGI-Pi has a rubber bumper to keep its pins from shorting into RasPi’s Ethernet jack, but they’re still pretty close and I recommend sticking electrical tape on RasPi’s Ethernet and USB connectors to make sure they don’t short to LOGI-Pi.

 

LOGI-Pi should also plug onto a RasPi Model B+ Expansion header J8, but the boards won’t be aligned as well and the RasPi B+ mounting holes aren’t compatible with LOGI-Pi.

 

The exact procedure for installing a LOGI-Pi is described in Logi-Pi - Out-Of-Box - Step by StepWhen you plug LOGI-Pi into RasPi, do so with the power off and make sure the connectors are aligned correctly.  If they aren’t, you could damage one or both boards.  For the RasPi Model B+, I think the proper way to align it is to plug LOGI-Pi into pins 1-26 of B+ Expansion header J8, i.e., the end labeled “J8”.  However, I’ve never tried it myself so I recommend checking that it’s correct before turning on power.

 

Once LOGI-Pi is installed, it can be difficult to view and probe RasPi, depending on what case you have.  In particular, the RasPi Status LEDs are covered up unless you can peek in from the side.  I use a home-made open-frame chassis with an opaque faceplate, so I can only see the glow of LEDs through a LOGI-Pi mounting hole.  (I have a 1.0 PCB so I can’t use LOGI-Pi’s standoffs.)

VertMount3a.jpg

Another consideration with RasPi is heat distribution.  The RasPi BCM2835 SoC and LAN9512/14 USB/Ethernet chips both get warm with normal use, and if they don’t have some airflow they can get quite hot, especially with some Model B 1.0 PCBs.  My vertical-mount chassis gets airflow across both sides of RasPi, which keeps the two chips from overheating.  LOGI-Pi leaves quite a bit of space between the two boards, so you probably won’t have problems.  My vertical-mount chassis works beautifully.

 

Alternatively, you can plug a 26-pin cable between RasPi and LOGI-Pi.  This allows you to use many standard RasPi cases.  I don’t know how long the cable can be before it causes signal integrity problems, especially with SPI.

 

By default, LOGI-Pi is powered from RasPi’s 5V rail, which usually comes from RasPi’s Micro USB power jack.  For small to medium experiments, RasPi provides enough power for LOGI-Pi without causing 5V to drop to the point that it causes RasPi power issues as described in the RasPi Hardware Wiki.  If you run into problems, power all your attached USB devices from an externally-powered USB hub so RasPi has more current available for LOGI-Pi.  Replacing the Micro USB power cable may also help: see Raspberry PI:- USB power cables, crashing and other problems.  If you don’t mind modifying your RasPi, you can replace its polyfuse with a single-blow fuse, which has lower resistance and therefore a lower voltage drop.

 

Your primary tool for diagnosing power problems is to measure the 5V level as described in the RasPi Troubleshooting Wiki.  You may need to probe LOGI-Pi instead of TP1 and TP2 on RasPi.  Be very careful probing the GPIO connector, because if you accidentally short 5V to 3.3V or to a signal you can kill your RasPi and/or LOGI-Pi.

 

Some RasPi Model B users back-power RasPi from an externally-powered USB hub.  This may provide higher 5V than going through the Micro USB cable.  I back-power my modified 1.0 Model B from a Motorola Atrix Lapdock which provides solid 5V power.

 

LOGI-Pi also has holes for optional headers if you want to provide it with its own power, e.g., for stand-alone applications.  If RasPi is also powered, don’t power LOGI-Pi separately 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.  You could use one of these headers to provide power to both LOGI-Pi and RasPi.  Be careful doing this, because it bypasses all of RasPi’s 5V protection circuits.  Be sure to check both the RasPi and LOGI-Pi schematics first.

 

For this ’blog I’m powering LOGI-Pi from RasPi’s Expansion header as usual.

 

LOGI-Pi has linear regulators to convert 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 Raspbian GNU/Linux for LOGI-Pi

 

To develop FPGA designs using LOGI-Pi, you will need two computers: an x86 PC to run Xilinx FPGA software, and your RasPi with LOGI-Pi installed.  The Xilinx software generates bitstreams, which you then transfer from the PC to your RasPi, and then you’ll run a program on RasPi to write bitstreams to LOGI-Pi.  There are various ways to do this, but for this ’blog I’ll concentrate on what I do with my RasPi setup.

 

I have a 256MB RasPi Model B running 2014-09-09 Raspbian Wheezy, downloaded from raspberrypi.org.  I use a Motorola Atrix Lapdock as my keyboard, mouse, and display.  I can also use a GNU/Linux PC running Ubuntu 12.04 LTS to talk to RasPi over Ethernet using a Terminal window with ssh (secure shell).  The Terminal window is convenient for LOGI-Pi development since I can use the PC’s display, keyboard, and mouse for everything once RasPi has booted.  The Lapdock display is useful for seeing if RasPi is booting and shutting down properly.

 

To talk to RasPi from the PC, you need to know the user name and password of a RasPi user who has superuser privileges.  I’m going to call this user george.  You can also use the default user pi if you don’t want to create a separate user.

 

You also need to know RasPi’s IP address. It’s normally assigned automatically using DHCP by a router or the PC.  My RasPi’s IP address is 192.168.0.106, which I found by giving the ifconfig command on RasPi using Lapdock.  For various ways to connect to RasPi so you can get its IP address, see Logi-Pi Quick Start Guide,

raspberrypi.org,  and RasPi Beginners Wiki.

 

Next, george needs a subdirectory for storing LOGI-Pi bitstreams.  I’ll assume this subdirectory is called LOGI with full RasPi path /home/george/LOGI or ~george/LOGI.

 

Finally, you need to enable RasPi’s SPI (Serial Peripheral Interconnect) device drivers and obtain or build LOGI-Pi’s FPGA loader logi_loader.  One way to do this is to load a pre-configured RasPi OS image from ValentF(x), as described in LOGI-Pi Quick Start Guide

 

If you prefer to use an official RasPi release from raspberrypi.org, you will need to do a fairly simple procedure to enable SPI and build logi_loader.  It’s described in another section of LOGI-Pi Quick Start Guide.

 

I found that with 2014-09-09 Raspbian Wheezy I could leave out a few steps.  First, check whether the SPI device drivers are already present.  You can tell by listing /dev on a RasPi terminal:

 

ls /dev

 

See if there are device drivers /dev/spidev0.0 and /dev/spidev0.1.  If not, SPI is “blacklisted” and you will need to enable it by editing /etc/modprobe.d/raspi-blacklist.conf.  First, change to the system directory /etc/modprobe.d and make a backup copy of raspi-blacklist.conf:

 

cd /etc/modprobe.d

sudo cp -p raspi-blacklist.conf raspi-blacklist.orig

 

Next, edit raspi-blacklist.conf using nano or a different text editor.  You’ll need to use sudo.  The original file looks something like this:

 

# blacklist spi and i2c by default (many users don't need them)

 

blacklist spi-bcm2708

blacklist i2c-bcm2708

blacklist snd-soc-pcm512x

blacklist snd-soc-wm8804

 

Comment out the bcm2708 lines so that SPI and I²C will be enabled next time you reboot:

 

# blacklist spi and i2c by default (many users don't need them)

 

#blacklist spi-bcm2708

#blacklist i2c-bcm2708

blacklist snd-soc-pcm512x

blacklist snd-soc-wm8804

 

Then save the file (ctl-X on nano).  Finally, reboot RasPi to apply the changed raspi-blacklist.conf:

 

sudo reboot

 

After RasPi reboots, /dev/spidev0.0 and /dev/spidev0.1 should be present.

 

Next we need to build logi_loader.  First see if it’s already in /usr/bin.  Otherwise you need to rebuild it from source code at GitHub.  2014-09-09 Raspbian Wheezy already has gcc, make, and git so you don’t need to install them.

 

First, decide where you want to build logi-tools, e.g., in your LOGI directory created earlier.  With the Internet attached to your RasPi via Ethernet, enter these commands on a RasPi terminal:

 

cd ~/LOGI

git clone https://github.com/fpga-logi/logi-tools.git

 

This downloads the source code and makefiles for all LOGI tools.  Next, build logi_loader:

 

cd logi-tools/logipi_loader

make

 

This compiles logi_loader from C source code.  Finally, copy logi_loader to /usr/bin:

 

sudo make install

 

The executable file /usr/bin/logi_loader should now exist.  You are now ready to write FPGA bitstreams to your LOGI-Pi.


Experiment 1:  Writing a Pre-tested Bitstream to LOGI-Pi

 

Now let’s try writing a bitstream to LOGI-Pi.  ValentF(x) has a nice blinking LED demo which they describe in the ValentF(x) Wiki.  However, they don’t provide a LOGI-Pi bitstream file for it.  You can build the bitstream using the instructions in LOGI-Pi Quick Start Guide but this is pretty complex for a first exercise.  So I’ve compiled the example and put the bitstream file logipi_blink.bit in LOGIdemo.zip.

 

The procedure in this section uses GNU commands entered in two PC Terminal windows, one for the PC and one for RasPi.  If you prefer GUIs and/or your PC is running Windows, ValentF(x) has other procedures with GUI equivalents for ssh and scp: SSH Guide, SCP Guide.  You can also enter RasPi commands on your attached RasPi keyboard and display instead of using ssh.

 

Here are the commands I use on my RasPi 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 RasPi with “RasPi$”.  I’ll use 192.168.0.106 as my RasPi IP address and george as my user name -- you’ll need to substitute your own.

 

  1. With power off, plug LOGI-Pi onto your RasPi as described earlier.

  2. Plug in your RasPi.  The RasPi and LOGI-Pi power LEDs should turn on and you should see lots of flashing on the RasPi Activity LED as the operating system boots (assuming the LED is visible with LOGI-Pi installed).

  3. Connect an Ethernet cable between RasPi and your router or Ethernet switch, or directly to your PC.  Once RasPi has booted the RasPi Link LED should come on.

  4. After giving RasPi time to boot, open a Terminal window on your PC and ping RasPi 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 RasPi’s Ethernet activity LED blink as the pings occur.

  5. Log onto RasPi using ssh and the IP address you verified in the last step.  On your PC, give the command:

        PC$ ssh george@192.168.0.106

    The first time I did this ssh asked me to confirm that this was correct.  Then ssh asks for george’s RasPi password.  If the RasPi 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 RasPi and you can enter GNU commands exactly as if you were on a RasPi serial port or directly-attached display and keyboard.

  6. You are now in george’s home directory on RasPi.  Let’s change to the LOGI directory:

        RasPi$ cd LOGI

  7. 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 logipi_blink.bit to that directory.  Let’s change to the PC’s LOGI directory:

        PC$ cd ~/LOGI

  8. You are now ready to transfer logipi_blink.bit from the PC to RasPi.  Use scp (secure copy) which in turn uses ssh for data transfers and authentication.  Here’s the PC command:

        PC$ scp logipi_blink.bit george@192.168.0.106:LOGI/.

    This copies logipi_blink.bit from the current PC directory to ~george/LOGI on RasPi, keeping the same file name.  scp will ask for george’s password to authenticate the transfer.

  9. On RasPi, make sure the file arrived by listing LOGI’s .bit files:

        RasPi$ ls -l *.bit

    Spartan-6 LX9 .bit files are approximately 340KB.

  10. The last step is to write logipi_blink.bit to LOGI-Pi’s FPGA:

        RasPi$ sudo logi_loader logipi_blink.bit

  11. If the transfer is successful, you should see a pretty blinking pattern on LOGI-Pi’s LED1 and LED0.

    If you look carefully, you will also see that LOGI-Pi’s Done LED is on.  It’s near pins 23 and 25 of the RasPi expansion connector.  The LED turns on very faintly for logipi_blink.bit.  This is because it’s pulled up by a weak FPGA resistor instead of being driven high by a transistor.

  12. When you are done playing with RasPi, be sure to shut it down properly so you don’t corrupt the file system:

        RasPi$ 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-Pi 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 Logi-Pi Quick Start Guide.  Gadget Factory also has some tutorials: Install ISE WebPack and Papilio Xilinx ISE WebPack VHDL Getting Started.

 

Experiment 2 creates a 4-bit binary counter that displays its two LSbs using LOGI-Pi 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-Pi’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    clk4Hz;

 

    reg   [9:0] P;             // Divide by 1000 prescaler.

    wire [10:0] nextP = P + 1;

    wire Pcarry = nextP[10];   // 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[14];   // Low-freq carry out, pulses at 4 Hz.

 

    always @(posedge Mclk)

    begin

        // 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;

    end

endmodule

 

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];

endmodule   

 

The counter includes asynchronous reset which we’ll connect to LOGI-Pi’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 UpCountPi(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[0];

    assign LED1 =  K[1];

    assign LED2 = !K[2];

    assign LED3 = !K[3];

endmodule   

 

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 UpCountPi.ucf:

 

NET Mclk LOC="P85"  | IOSTANDARD=LVTTL | PERIOD=20ns;

NET PB0  LOC="P102" | IOSTANDARD=LVTTL;  # PB0 = press to reset

NET PB1  LOC="P101" | IOSTANDARD=LVTTL;  # PB1 = press to hold

NET LED0 LOC="P105" | IOSTANDARD=LVTTL;  # LED0

NET LED1 LOC="P104" | IOSTANDARD=LVTTL;  # LED1

NET LED2 LOC="P5"   | IOSTANDARD=LVTTL;  # PMOD1-1

NET LED3 LOC="P2"   | IOSTANDARD=LVTTL;  # PMOD1-2

 

I found the pin numbers in the LOGI-Pi R1.0 schematics.  The LOGI-Pi Quick Start Guide shows you how to find them.  In the 4/23/2014 LOGI-Pi R1.1 schematics the PMOD1 and PMOD2 connections appear to be exchanged on sheet 4.  That’s OK because they’re also exchanged on sheet 6 so the errors cancel out.

 

Once I have added UpCountPi.ucf to root module UpCountPi 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 UpCountPi.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 UpCountPi.bit to RasPi and LOGI-Pi.  This is basically the same as steps 7-11 in Experiment 1:

 

  1. On the PC, change to the directory that contains UpCountPi.bit, in my case LOGI/LOGIdemo.

        PC$ cd ~/LOGI/LOGIdemo

  2. Transfer UpCountPi.bit from the PC to RasPi using scp:

        PC$ scp UpCountPi.bit george@192.168.0.106:LOGI/.

  3. On RasPi, make sure the file arrived by listing LOGI’s .bit files:

        RasPi$ ls -l *.bit

  4. Write UpCountPi.bit to LOGI-Pi’s FPGA using logi_loader:

        RasPi$ sudo logi_loader UpCountPi.bit

  5. 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 UpCountPi.ucf are available in LOGIdemo.zip, along with UpCountPi.bit.

 

Conclusion

 

This was my first experience with LOGI-Pi 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 about device driver blacklists and git than the FPGA-specific tasks.

 

This is a simple introduction to using LOGI-Pi, intended to help you see results with minimal effort and frustration.  LOGI-Pi 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.  Raspberry Pi is a trademark of the Raspberry Pi Foundation.]

Are you new to FPGAs? Want to know the difference between your LEs and your DSP blocks?

 

Altera have come to the rescue with this handy FPGA for Dummies ebook.

 

element14FPGAfordummies.png

 

Get it Now >>>

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:

 

LOGI-BonePCBrev1.png

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.

 

Powering LOGI-Bone

 

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

 

Now let’s try writing a bitstream to LOGI-Bone.  ValentF(x) has a nice blinking LED demo which they describe at the ValentF(x) Wiki.  You can download the bit file logibone_r1_blink.bit from GitHub.

 

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.

 

  1. 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.

  2. 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.

  3. 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.

  4. 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.

  5. Log onto BBone using ssh and the IP address you verified in the last step.  On your PC, give the command:

        PC$ ssh george@192.168.0.106

    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.

  6. You are now in george’s home directory on BBone.  Let’s change to the LOGI directory:

        BBone$ cd LOGI

  7. 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

  8. 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 george@192.168.0.106: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.

  9. 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.

  10. 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.

  11. 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.

  12. 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    clk4Hz;

 

    reg   [9:0] P;             // Divide by 1000 prescaler.

    wire [10:0] nextP = P + 1;

    wire Pcarry = nextP[10];   // 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[14];   // Low-freq carry out, pulses at 4 Hz.

 

    always @(posedge Mclk)

    begin

        // 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;

    end

endmodule

 

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];

endmodule   

 

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[0];

    assign LED1 =  K[1];

    assign LED2 = !K[2];

    assign LED3 = !K[3];

endmodule   

 

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:

 

  1. On the PC, change to the directory that contains UpCountBone.bit, in my case LOGI/LOGIdemo.

        PC$ cd ~/LOGI/LOGIdemo

  2. Transfer UpCountBone.bit from the PC to BBone using scp:

        PC$ scp UpCountBone.bit george@192.168.0.106:LOGI/.

  3. On BBone, make sure the file arrived by listing LOGI’s .bit files:

        BBone$ ls -l *.bit

  4. Write UpCountBone.bit to LOGI-Bone’s FPGA using dd:

        BBone$ sudo dd if=UpCountBone.bit of=/dev/logibone bs=4M

  5. 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.

 

Conclusion

 

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.]