Lesson 11/2544%
MODULE 11 OF 25 15 MIN FPGA FUNDAMENTALS

Lookup Tables (LUT)

Understand how a 64-bit SRAM cell implements any Boolean function — the heart of every FPGA logic block. Learn LUT6 structure, truth tables, distributed RAM, shift register, and chaining modes.

What is a LUT?

A Look-Up Table (LUT) is a small SRAM that stores the truth table of any Boolean function. A 6-input LUT (LUT6) contains 26 = 64 memory cells, each holding one bit. The six address inputs A1–A6 select one of the 64 cells, and the stored value appears at the output. This single mechanism allows an FPGA to implement any logic function — AND, OR, XOR, complex combinational expressions — without using physical logic gates.

During bitstream loading, the synthesis and implementation tools program each LUT's 64 SRAM cells with the correct truth table values. A new bitstream reprograms those cells to implement a completely different function — this is the core of FPGA reconfigurability.

Key Concept The LUT6 can implement any Boolean function of up to 6 inputs in a single pass. The synthesis tool determines the optimal 64-bit INIT value during synthesis — you never need to set it manually for normal designs.

LUT6 Internal Structure

The LUT6 in Xilinx 7-series (and later families) has the following internal organization:

  • Memory array: 64 × 1-bit SRAM cells
  • Address inputs: A1–A6 (6-bit address, 26 = 64 entries)
  • O6 output: Full LUT6 mode — uses all 64 bits, all 6 inputs active
  • O5 output: LUT5 mode — uses only the first 32 bits (A1–A5 address), A6 ignored
  • Dual-output mode: O5 and O6 can implement two independent 5-input functions simultaneously if they share inputs A1–A5
graph LR A1[A1] --> MEM[64x1-bit\nSRAM Memory] A2[A2] --> MEM A3[A3] --> MEM A4[A4] --> MEM A5[A5] --> MEM A6[A6] --> MEM MEM --> O6[O6 Output] MEM --> O5[O5 Output\nFirst 32-bits only] O6 --> FF[D Flip-Flop\nOptional register] FF --> Q[Registered output]

Truth Table and INIT String

The INIT parameter is the 64-bit hexadecimal value programmed into the LUT. Each bit in the INIT string corresponds to one row of the truth table, with bit position equal to the decimal value of {A6,A5,A4,A3,A2,A1}.

Example — 6-input AND gate: The output is 1 only when all six inputs are 1, which is address 63 (binary 111111). So only bit 63 of INIT is 1:

// 6-input AND gate — only address 63 (all inputs high) gives output 1
INIT = 64'h8000000000000000

// 3-input AND (A1, A2, A3) — address 7 (binary 000111) gives output 1
INIT = 64'h0000000000000080

// 6-input XOR — output 1 when odd number of inputs are high
INIT = 64'h6996966996696996

// 4-input MUX (A5=select, A1-A4=data)
// Automatically inferred by synthesis from Verilog: assign y = sel ? d1 : d0;
Engineering Tip — LUT Fractioning LUT6 can simultaneously output two independent 5-input functions (O5 and O6) if they share inputs A1–A5. Vivado automatically exploits this to reduce LUT count — called "LUT fractioning." A design that appears to need 100 LUTs may fit in 70 after fractioning.

LUT as a 2:1 Multiplexer

When A6 acts as a select signal, the LUT6 naturally implements a 2:1 MUX between two independent 5-input functions computed on A1–A5. This is fundamental to how wide multiplexers and priority encoders are built in FPGA fabric. A 4:1 MUX uses two LUTs plus the F7MUX.

LUT Chaining — F7MUX and F8MUX

Each Slice contains dedicated multiplexers that chain LUT6 outputs:

  • F7MUX: Combines two LUT6 O6 outputs with a select signal → implements any 7-input function
  • F8MUX: Combines two F7MUX outputs → implements any 8-input function
  • These paths use dedicated silicon wires, not the general routing matrix — adding only ~0.1ns delay
  • Critical for wide address decoding: 16:1 MUX uses 2 F7MUXes + 1 F8MUX = 4 LUTs

LUT as Distributed RAM (Slice M Only)

In Slice M (not Slice L), the LUT SRAM can be written — making it a 64×1-bit RAM. Key properties:

  • Write port: Synchronous — write occurs on clock edge when write enable is asserted
  • Read port: Asynchronous by default — data available immediately without waiting for a clock
  • Combining LUTs: Four LUTs in a Slice M → 256×1-bit RAM (or 64×4-bit RAM)
  • Use cases: Small register files, FIFOs, coefficient tables, shift registers

LUT as Shift Register (SRL)

A single LUT6 in Slice M can be configured as a 32-bit shift register (SRL32) or 16-bit shift register (SRL16E):

  • Synchronous shift operation on clock edge
  • Dynamic tap selection via 5-bit address input — read any bit position at runtime
  • Extremely efficient: replaces 32 flip-flops with 1 LUT for delay lines
  • Used for: pipeline delay compensation, audio buffers, deserializers
Interview Question Q: How many different Boolean functions can a LUT6 implement?
A: 264 distinct 6-input Boolean functions. Every possible truth table configuration of 6 inputs can be stored in the 64 SRAM cells. This is why LUT6 can implement literally any 6-input logic function.

LUT Operating Modes

Mode Address Bits Memory Depth Output Use Case
LUT6 Logic A1–A6 (6-bit) 64 bits O6 Any 6-input Boolean function
LUT5 Logic A1–A5 (5-bit) 32 bits O5 Any 5-input Boolean function (A6 unused)
Dual 5-input A1–A5 shared 32+32 bits O5 + O6 Two independent 5-input functions simultaneously
Distributed RAM A1–A6 (write addr) 64×1-bit SRAM O6 (async read) Small LUTs, register files (Slice M only)
SRL32 5-bit tap select 32-bit shift reg Tap output Delay lines, FIFOs, pipeline alignment
ROM A1–A6 64 bits (fixed) O6 Coefficient tables, constant lookup

LUT Size Comparison Across FPGA Vendors

Vendor / Family LUT Inputs SRAM Cells Dual Output Notes
Xilinx 7-series / UltraScale (AMD) 6 64 Yes (O5+O6) Industry-leading — LUT6 dual output for fractioning
Intel (Altera) ALM 8 (adaptive) 256 (shared) Yes (2×4-input) Adaptive Logic Module — configures as two 4-input or one 6-input
Lattice ECP5 4 16 No Simpler LUT4; more LUTs needed for 5-6 input functions
Lattice iCE40 4 16 No Ultra-low power; basic LUT4 architecture
Microchip PolarFire 4 16 Partial 4-input LUT with carry and optional register

LUT Utilization Reporting in Vivado

After synthesis or implementation, Vivado's Utilization Report shows:

+----------------------------+-------+------+------------+
|          Site Type         |  Used | Avail | Util% |
+----------------------------+-------+------+------------+
| Slice LUTs                 |  4832 | 20800 | 23.23 |
|   LUT as Logic             |  4120 | 20800 | 19.81 |
|   LUT as Memory            |   512 |  9600 |  5.33 |
|     LUT as Distributed RAM |   384 |  9600 |  4.00 |
|     LUT as Shift Register  |   128 |  9600 |  1.33 |
+----------------------------+-------+------+------------+

Each Slice contains 4 LUTs. A design using 4832 Slice LUTs occupies approximately 1208 Slices. "LUT as Logic" is pure combinational/sequential logic. "LUT as Memory" means the SRAM write capability is used (Slice M only).

Common Mistake — Manual LUT Optimization New FPGA engineers try to optimize LUT count manually by rewriting logic. Let the synthesis tool do it — Vivado's optimizer will pack LUTs more efficiently than manual effort in almost every case. Focus on writing clean, readable RTL and proper architecture; optimize only if you genuinely exceed device capacity.
Best Practice — LUT Input Count Design logic to use 4–6 inputs per LUT for best efficiency. Functions needing 7+ inputs require multiple LUTs and F7/F8 MUXes, increasing delay by one routing hop (~0.1–0.3ns). Break large Boolean expressions into 5-6 input sub-expressions in RTL.

Interactive LUT Simulator

Toggle inputs A1–A6 to see which truth table address is selected and what the LUT output is. Choose a preset function to load its INIT value.

Preset Functions

Input Values

Address (A6..A1)
000000 = 0
LUT Output (O6)
0
Function
4-input AND

INIT Value (64-bit hex)

64'h0000000000008000

Truth Table (scroll to see all 64 rows)

Addr A6 A5 A4 A3 A2 A1 Out

Knowledge Check

1. How many memory cells are in a LUT6?
  • 16
  • 32
  • 64
  • 128
Correct! 26 = 64 cells. Six address inputs select among 64 possible SRAM cells, one per row of the truth table.
2. What is the LUT6 INIT parameter?
  • The default output value when all inputs are 0
  • The 64-bit hexadecimal truth table value programmed into the LUT
  • The initialization delay in nanoseconds
  • The number of inputs used by the function
Correct! INIT is the 64-bit hex value stored in the LUT SRAM cells. Each bit corresponds to one row of the truth table. Synthesis tools compute and set this automatically.
3. LUT5 mode (O5 output) uses how many of the 64 cells?
  • 16
  • 32
  • 48
  • 64
Correct! LUT5 mode uses inputs A1–A5 only (25 = 32 cells). A6 is not used, so only the first 32 of the 64 SRAM cells are addressed.
4. Can a LUT6 output two independent functions simultaneously?
  • No — one LUT can only produce one output
  • Yes — using O5 and O6 outputs for two 5-input functions sharing A1–A5
  • Yes — but only for XOR functions
  • Only with external multiplexers
Correct! When two 5-input functions share the same inputs A1–A5, O5 gives one function (lower 32 bits of INIT) and O6 gives another (upper 32 bits). This is LUT fractioning.
5. Which Slice type allows the LUT to be used as distributed RAM?
  • Slice L only
  • Slice M only
  • Both Slice L and Slice M
  • Any Slice with a BRAM adjacent
Correct! Only Slice M has the write circuitry needed to use the LUT SRAM as distributed RAM or SRL. Slice L LUTs are read-only (used purely as logic).
6. What is F7MUX used for?
  • Connecting two CLBs across the routing matrix
  • Multiplexing flip-flop outputs to I/O pins
  • Combining two LUT6 outputs for 7-input functions
  • Selecting between clock domains
Correct! F7MUX is a dedicated multiplexer inside the Slice that combines the O6 outputs of two LUT6s with a select input to implement any 7-input function in just two LUT delays.

Practical Exercise

Manual LUT Mapping

(a) Write the 64-bit INIT value for a 3-input majority function. The output is 1 when 2 or more of A1, A2, A3 are high. Which address entries (0–63) should have output = 1? (Hint: {A3,A2,A1} must have popcount ≥ 2.)

(b) Write the INIT for a 6-input XOR gate. The output is 1 when an odd number of inputs are high. (Hint: try toggling inputs in the simulator above — the XOR preset shows you the answer.)

(c) In Vivado, create a Verilog module: assign y = a & b & c; After synthesis, open the schematic (F4), double-click the LUT primitive, and find its INIT value in the properties panel. Does it match your hand-calculated value?

(d) Change the logic to a 7-input AND. Re-synthesize. How many LUTs does Vivado use now? What F7/F8 MUX structures appear in the schematic?