The generic building block to make a FPGA is the logic block, which is composed of look-up table and flip-flop. Each FPGA maker has its own design and terms for those Logic Element:
- Xilinx Spartan 6: Slice M, L, or X with 4 LUT (6 inputs) and 8 Flip-flops, packed in a CLB (Configurable Logic Block).
- Altera: LE (Logic Element) with one LUT and one Flip-Flop, packed in a LAB (Logic Array Block).
[UG384] is a dedicated documentation about the internal design of the CLB and its slices.
Slice M configuration
The slice M is a superset of the other slices (L and X) in the Spartan 6:

The creator of the FpgaTools project [1] reverse-engineered the bitstream protocol to configure those logic blocks. From the source code, I documented the configuration registers here [2], and added a corresponding configuration request to my live reconfiguration protocol (FLR [3]).
Here is a simple Verilog module to use one slice in the Spartan 6 fabric:
module slice(
clk,
in,
out,
clear
);
input clk;
input clear;
input [3:0] in;
output [3:0] out;
reg [3:0] out;
always @(posedge clk or posedge clear) begin
// async reset
if(clear) out <= 4'b0000;
else if(in == 4'b1011) out <= 4'b0000;
else if(in == 4'b1010) out <= 4'b1001;
else if(in == 4'b0101) out <= 4'b0010;
else if(in == 4'b1000) out <= 4'b0100;
else if(in == 4'b0011) out <= 4'b1000;
else if(in == 4'b0100) out <= 4'b1001;
else if(in == 4'b1111) out <= 4'b1111;
else out <= in;
end
endmodule
The above code produce this RTL design in Xilinx ISE:

Note1: the BUFGP is a global buffer which is not located in IOB.
Note2: The synthesis tool will tend to move the D flip-flop of the registered output in the IOB for better performances (see previous post for disabling this optimization).
Note3: Not all slime M features are used here (no LUT6, no dual flip-flop output, no carry logic...).
The location and the choice of using a LUT6 or a LUT5 for each LUT can be forced by generating the following constraints using PlanAhead:
INST "Mmux_in[3]_GND_1_o_mux_13_OUT11" BEL = D5LUT; INST "Mmux_in[3]_GND_1_o_mux_13_OUT11" LOC = SLICE_X20Y61; INST "Mmux_in[3]_GND_1_o_mux_13_OUT21" BEL = C5LUT; INST "Mmux_in[3]_GND_1_o_mux_13_OUT21" LOC = SLICE_X20Y61; INST "Mmux_in[3]_GND_1_o_mux_13_OUT31" BEL = B5LUT; INST "Mmux_in[3]_GND_1_o_mux_13_OUT31" LOC = SLICE_X20Y61; INST "Mmux_in[3]_GND_1_o_mux_13_OUT41" BEL = A5LUT; INST "Mmux_in[3]_GND_1_o_mux_13_OUT41" LOC = SLICE_X20Y61;
It seems that only FPGA Editor will the show the actual chosen configuration:

- There were two possible choices:
- going through the first flip-flop and DMUX out.
- going through the second flip-flop and DQ out.
Spartan 6 bitstream
Slices are configured in minors 20, 23 (M only), and 25 (L) or 26 (M).
/* frame 1961 (row 3, maj 15, min 26) */
{
/* 127549 */ 0x0000, /* dw 127465 empty */
/* 127550 */ 0x0090, /* dw 127466 _____ */
/* 127551 */ 0x0000, /* dw 127467 empty */
/* 127552 */ 0x0000, /* dw 127468 empty */
/* 127553 */ 0x0000, /* dw 127469 empty */
/* 127554 */ 0x0090, /* dw 127470 _____ */
/* 127555 */ 0x0000, /* dw 127471 empty */
/* 127556 */ 0x0000, /* dw 127472 empty */
/* 127557 */ 0x0800, /* dw 127473 _____ */
/* 127558 */ 0x0404, /* dw 127474 _____ */
/* 127559 */ 0x0002, /* dw 127475 _____ */
/* 127560 */ 0x0010, /* dw 127476 _____ */
[...]
The 4 last words show the multiplexers configuration: 0x1 for OUTMUX_D(5Q), 0x2 for OUTMUX_B(5Q), 0x4 for OUTMUX_C(5Q), 0x8 for OUTMUX_D(5Q). One more bit set to one for the flip-flop reset mode (synchronous).
[UG384] | Spartan-6 FPGA Configurable Logic Block http://www.xilinx.com/support/documentation/user_guides/ug384.pdf |
[1] | FpgaTools GitHub repository, https://github.com/Wolfgang-Spraul/fpgatools |
[2] | Slice M configuration http://vjordan.info/flr/slicem_config.html |
[3] | FPGA Live reconfiguration protocol http://vjordan.info/flr/ |