What is an FPGA ?

From ValentFx Wiki
Jump to: navigation, search


What is inside a FPGA ?

An FPGA is sometimes called a "sea of gates", meaning that is contains thousands of logic elements with a programmable interconnect. Compared to a micro-controller or a micro processor, an FPGA does not execute a program (structured sequence of instructions) but executes a logic architecture composed of basic logic elements. This means that you can design your processors/controllers to be programmed into the FPGA.

By default and FPGA contains a set of logic functions :

  • LUT (Look-up table)
  • D-latches
  • N input Muxes

and vendor specific functions :

  • DSP blocks (multipliers, adders ...)
  • Memory blocks (dual-port block ram)
  • PLL (Phased Lock Loop) to generate multiple frequencies from a single clock source
  • External memory drivers (SDRAM/DDR controllers)
  • Processor core (ARM, PowerPC ...)
  • Gigabit interfaces (LVDS)

These logic functions are organized in a CLB (Configurable Logic Block), whose configuration (logic functions connections, number, configuration) and name is seller specific (slices, blocks ...). These CLBs are arranged onto a interconnect matrix which can connect any of the CLB to another to create a logic path that execute a given logic function. The CLB and matrix interconnect are controlled by a SRAM of FLASH floor-plan whose bits individually control CLBs parameters (LUT inputs, logic connect, ...) and matrix interconnect. SRAM FPGA are volatile meaning that turning its power off will erase the configuration and will return it to blank. FLASH based FPGA have a lower power consumption (FLASH does is not volatile and consume less power) but can be reprogrammed a limited number of time (FLASH is subject to wearing).











What makes it different ?


The advantage of FPGA over micro-controller are :

  • Parallelism : A micro-controller can execute instruction sequentially while a FPGA can execute a lot of logic functions in parallel.
  • Frequency : Even low-budget FPGA can execute functions at very high frequency (> Ghz) depending on the design. More-over on can tune the exact frequency its design is needs to run at to achieve its time constraints thus allowing to save energy.
  • Pin-count : FPGA usually comes with a high GPIO count. Moreover each pin can be configured to achieve any of the functions programmed into the FPGA. A micro-controller usually have pins dedicated to special functions (SPI, I2C, GPIO, clocks, UART ...), and you need to get the device that will match your application. An FPGA is very flexible in the way you can connect logic functions to any of the pins, thus PCB routing can be eased.

... and the drawbacks:

  • Development cost/time : FPGA configuration is designed through an Hardware Description Language (HDL). These languages comes with concept very different than software languages as they do not describe a sequence of instruction but describe a logic functions by connecting logic resources. More-over debugging a FPGA design means debugging at the signal level. This means you have to trace the execution of your description by watching your design signals evolving in terms of logic ones an zero. 
  • Non soldering-friendly packages : Most FPGA comes in high pin-count packages with low pitch or BGA (Ball Grid Array).
  • Price : FPGA are expensive compared to micro-controller. The price of FPGA is justified by the low volume that are produced (compared to micro-controller) and the surface of silicon they use. As you design your own architecture you will leave some of the fabric unused meaning that you pay even for what you don't use.
  • Documentation : The documentation of FPGA is usually scattered in a lot of lengthy pdf files. 
  • Routing : PCB routing can be seen as an advantage of the FPGA as any of the pins can be connected to any of the functions. But when you are dealing with high frequency designs the pins connecting can affect the max frequency your design can reach. Thus you need to take your design into account while routing your PCB. FPGA can also consume quite a lot of power and one needs to take a lot of consideration while routing power rails and regulators of the FPGA.

What are FPGA used for ?

FPGA are usually used for low-volume high performance application. When one need to execute a given function with the best performance, nothing beats FPGA (even GPU don't). FPGA can also be used as a prototyping stage for ASIC (Application Specific Integrated Circuit) or SOC (System On Chip). Producing an ASIC is really expensive and can only be justified by high production volume or sensitive applications (aeronautics, space). To prototype these ASIC FPGA are usualy used to debug the design and tune parameters. When the design is ready the description is compiled into a circuit that can be produced using classical integrated circuit production techniques. 


Basic FPGA design

To design a simple function such as counter one needs to describe it in term of logic elements. To start this design we first need to understand what is a counter in term of logic. The tiniest counter you can design is the one bit counter. A one bit counter can only count from zero to one and then loop-back to zero (one modulus). A one bit counter is a component with the following interfaces :

  • A clock port
  • A reset port that reset the counter to zero
  • A enable port, that enable counting
  • A count port that output the current counter value


We can textually describe the counter behavior by the following :
The counter count for each rising edge of the clock when enable is equal to logic one. The counter reset to zero when the reset port equal to zero whatever state the clock is (asynchronous active low reset).

From this given description we can use the VHDL language to formalize the following design:

library IEEE;

entity one_bit_counter is
    clk, resetn : in std_logic;
    en : in std_logic ;
    count : out std_logic ;
end one_bit_counter;

architecture RTL of one_bit_counter is
    signal count_q, count_d : std_logic ;
    process(clk, resetn)
                if resetn = '0' then
                    count_q <= '0' ;
        elsif clk'event and clk = '1' then    
                       count_q <= count_d ;
        end if;
    end process ;
        with en select 
             count_d <= (NOT count_q) when '1',
                        count_q when others ;

    count <= count_q;
end RTL;


The component we just designed is synthesized into the following logic design :



f you give a look at the diagram and then the code you can understand that :

  • A process sensitive to a clock and with the rising edge condition (clk'event and clk='1') is synthesized into a D-latch. 
  • The with-select statement is synthesize into a mux.

 one bit counter is somewhat useless on its own but the advantage of HDL language is that they are component based to ease re-use. Thus we can use this one-bit counter and instantiate it to create a 8-bit counter. To realize a 8bit counter from a one bit counter you need to decide when each counter is going to count. Lets analyze a 8bit counter counting sequence:
"00000000" => "00000001" => "00000010" => "00000011" => "00000100" ...
From this sequence we can infer the LUT that controls the enable signal of each of the 1bit counters :

en en_bn-1 bn-1 en_bn
0 x x x
1 1 0 0
1 0 1 0
1 1 1 1


This leads to the following code :


library IEEE;

entity eight_bit_counter is
    clk, resetn : in std_logic;
    en : in std_logic ;
    count : out std_logic_vector(7 downto 0) ;
end eight_bit_counter;

architecture RTL of eight_bit_counter is
       component one_bit_counter is
            clk, resetn : in std_logic;
            en : in std_logic ;
            count : out std_logic ;
       end component;
       signal en_count : std_logic_vector(7 downto 0) ;
       signal count_q : std_logic_vector(7 downto 0) ;
       gen_counter : for i in 0 to 7 generate
           counter_i : one_bit_counter
                         port map(
                           clk => clk,
                           resetn => resetn,
                           en => en_count(i),
                           count => count_q(i)
       end generate;
       en_count(0) <= en ;
       gen_lut : for i in 1 to 7 generate
          en_count(i) <= '1' when en_count(i-1) = '1' and count_q(i-1) = '1' and en = '1' else
                         '0' ; 
       end generate;

       count <= count_q ;
end RTL;


which synthesize as multiple folowing logic functions connected in a chain.



In the code listed above, the generate statement is used to generate multiple instance of a given statement or component. The code also shows that a LUT can be created using the when statement. This statement also takes care or the priority between its multiple conditions.







Personal tools